Class CompactMap<K,V>
- All Implemented Interfaces:
Map<K,
V>
- Direct Known Subclasses:
CompactCIHashMap
,CompactCILinkedMap
,CompactLinkedMap
Map
implementation that adapts its internal storage structure
to minimize memory usage while maintaining excellent performance.
Creating a CompactMap
There are two primary ways to create a CompactMap:1. Using the Builder Pattern (Recommended)
// Create a case-insensitive, sorted CompactMap
CompactMap<String, Object> map = CompactMap.<String, Object>builder()
.caseSensitive(false)
.sortedOrder()
.compactSize(80)
.build();
// Create a CompactMap with insertion ordering
CompactMap<String, Object> ordered = CompactMap.<String, Object>builder()
.insertionOrder()
.mapType(LinkedHashMap.class)
.build();
Type Inference and Builder Usage
Note the type witness (<String, Object>
) in the example above. When using the builder pattern
with method chaining, you may need to provide a type witness to help Java's type inference:
// Alternative approach without type witness
Builder<String, Object> builder = CompactMap.builder();
CompactMap<String, Object> map2 = builder
.caseSensitive(false)
.sortedOrder()
.build();
The type witness (<String, Object>
) is required due to Java's type inference
limitations when method chaining directly from the builder() method. If you find the
type witness syntax cumbersome, you can split the builder creation and configuration
into separate statements as shown in the second example above.
2. Using Constructor
// Creates a default CompactMap that scales based on size
CompactMap<String, Object> map = new CompactMap<>();
// Creates a CompactMap initialized with entries from another map
CompactMap<String, Object> copy = new CompactMap<>(existingMap);
In the examples above, the behavior of the CompactMap will be that of a HashMap,
while using the minimal amount of memory possible to hold the contents. The CompactMap
has only one instance variable.
Configuration Options
When using the Builder pattern, the following options are available:Method | Description | Default |
---|---|---|
caseSensitive(boolean) |
Controls case sensitivity for string keys | true |
compactSize(int) |
Maximum size before switching to backing map | 70 |
mapType(Class) |
Type of backing map when size exceeds compact size | HashMap.class |
singleValueKey(K) |
Special key that enables optimized storage when map contains only one entry with this key | "id" |
sourceMap(Map) |
Initializes the CompactMap with entries from the provided map | null |
sortedOrder() |
Maintains keys in sorted order | unordered |
reverseOrder() |
Maintains keys in reverse order | unordered |
insertionOrder() |
Maintains keys in insertion order | unordered |
Example with Additional Properties
CompactMap<String, Object> map = CompactMap.builder()
.caseSensitive(false)
.sortedOrder()
.compactSize(80)
.singleValueKey("uuid") // Optimize storage for single entry with key "uuid"
.sourceMap(existingMap) // Initialize with existing entries
.build();
Internal Storage States
As elements are added to or removed from the map, it transitions through different internal states to optimize memory usage:State | Condition | Storage | Size Range |
---|---|---|---|
Empty | val == EMPTY_MAP |
Sentinel value | 0 |
Single Entry | Direct value or Entry | Optimized single value storage | 1 |
Compact Array | val is Object[] |
Array with alternating keys/values | 2 to compactSize |
Backing Map | val is Map |
Standard Map implementation | > compactSize |
Implementation Note
This class uses runtime optimization techniques to create specialized implementations based on the configuration options. When a CompactMap is first created with a specific combination of options (case sensitivity, ordering, map type, etc.), a custom class is dynamically generated and cached to provide optimal performance for that configuration. This is an implementation detail that is transparent to users of the class.
The generated class names encode the configuration settings. For example:
CompactMap$HashMap_CS_S70_id_Unord
- A case-sensitive, unordered map with HashMap backing, compact size of 70, and "id" as single value keyCompactMap$TreeMap_CI_S100_UUID_Sort
- A case-insensitive, sorted map with TreeMap backing, compact size of 100, and "UUID" as single value keyCompactMap$LinkedHashMap_CS_S50_Key_Ins
- A case-sensitive map with insertion ordering, LinkedHashMap backing, compact size of 50, and "Key" as single value key
For developers interested in the internal mechanics, the source code contains detailed documentation of the template generation and compilation process.
Note: As elements are removed, the map will transition back through these states in reverse order to maintain optimal memory usage.
While subclassing CompactMap is still supported for backward compatibility, it is recommended to use the Builder pattern for new implementations.
- Author:
- John DeRegnaucourt ([email protected])
Copyright (c) Cedar Software LLC
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
License
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final class
Builder class for creating customized CompactMap instances.static class
Comparator implementation for CompactMap key ordering.class
A specialized Map.Entry implementation for single-entry storage in CompactMap.protected static enum
-
Field Summary
Fields -
Constructor Summary
ConstructorsConstructorDescriptionConstructs an empty CompactMap with the default configuration.CompactMap
(Map<K, V> other) Constructs a CompactMap initialized with the entries from the provided map. -
Method Summary
Modifier and TypeMethodDescriptionstatic <K,
V> CompactMap.Builder <K, V> builder()
Returns a builder for creating customized CompactMap instances.void
clear()
Removes all mappings from this map.protected int
Returns the threshold size for compact array storage.protected int
computeKeyHashCode
(Object key) Computes hash code for map keys, handling special cases.protected int
computeValueHashCode
(Object value) Computes hash code for map values, handling special cases.boolean
containsKey
(Object key) Returnstrue
if this map contains a mapping for the specified key.boolean
containsValue
(Object value) Returnstrue
if this map maps one or more keys to the specified value.entrySet()
Returns aSet
view of the mappings contained in this map.boolean
Compares the specified object with this map for equality.Returns the value to which the specified key is mapped, ornull
if this map contains no mapping for the key.protected CompactMap.LogicalValueType
Returns the current storage state of this map.Creates the backing map instance when size exceeds compactSize.protected String
Returns the ordering strategy for this map.protected K
Returns the designated key for optimized single-value storage.int
hashCode()
Returns the hash code value for this map.protected boolean
Determines if String keys are compared case-insensitively.boolean
isEmpty()
keySet()
Returns a Set view of the keys in this map.Deprecated.Deprecated.Associates the specified value with the specified key in this map.void
Copies all mappings from the specified map into this map.Removes the mapping for the specified key from this map if present.int
size()
Returns the number of key-value mappings in this map.toString()
Returns a string representation of this map.values()
Returns aCollection
view of the values contained in this map.Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
Methods inherited from interface java.util.Map
compute, computeIfAbsent, computeIfPresent, forEach, getOrDefault, merge, putIfAbsent, remove, replace, replace, replaceAll
-
Field Details
-
COMPACT_SIZE
- See Also:
-
CASE_SENSITIVE
- See Also:
-
MAP_TYPE
- See Also:
-
SINGLE_KEY
- See Also:
-
SOURCE_MAP
- See Also:
-
ORDERING
- See Also:
-
UNORDERED
- See Also:
-
SORTED
- See Also:
-
INSERTION
- See Also:
-
REVERSE
- See Also:
-
val
-
-
Constructor Details
-
CompactMap
public CompactMap()Constructs an empty CompactMap with the default configuration.This constructor ensures that the `compactSize()` method returns a value greater than or equal to 2.
- Throws:
IllegalStateException
- ifcompactSize()
returns a value less than 2
-
CompactMap
Constructs a CompactMap initialized with the entries from the provided map.The entries are copied from the provided map, and the internal representation is determined based on the number of entries and the
compactSize()
threshold.- Parameters:
other
- the map whose entries are to be placed in this map- Throws:
NullPointerException
- ifother
is null
-
-
Method Details
-
size
public int size()Returns the number of key-value mappings in this map.If the map contains more than
Integer.MAX_VALUE
elements, returnsInteger.MAX_VALUE
. -
isEmpty
public boolean isEmpty() -
containsKey
Returnstrue
if this map contains a mapping for the specified key.- Specified by:
containsKey
in interfaceMap<K,
V> - Parameters:
key
- the key whose presence in this map is to be tested- Returns:
true
if this map contains a mapping for the specified key;false
otherwise
-
containsValue
Returnstrue
if this map maps one or more keys to the specified value.- Specified by:
containsValue
in interfaceMap<K,
V> - Parameters:
value
- the value whose presence in this map is to be tested- Returns:
true
if this map maps one or more keys to the specified value;false
otherwise
-
get
Returns the value to which the specified key is mapped, ornull
if this map contains no mapping for the key.A return value of
null
does not necessarily indicate that the map contains no mapping for the key; it is also possible that the map explicitly maps the key tonull
. -
put
Associates the specified value with the specified key in this map. If the map previously contained a mapping for the key, the old value is replaced.- Specified by:
put
in interfaceMap<K,
V> - Parameters:
key
- key with which the specified value is to be associatedvalue
- value to be associated with the specified key- Returns:
- the previous value associated with key, or
null
if there was no mapping for key. - Throws:
NullPointerException
- if the specified key is null and this map does not permit null keysClassCastException
- if the key is of an inappropriate type for this map
-
remove
Removes the mapping for the specified key from this map if present. -
putAll
Copies all mappings from the specified map into this map.If resulting size would exceed compactSize, transitions directly to map storage. Otherwise, adds entries individually, allowing natural transitions to occur.
- Specified by:
putAll
in interfaceMap<K,
V> - Parameters:
map
- mappings to be stored in this map- Throws:
NullPointerException
- if the specified map is null
-
clear
public void clear()Removes all mappings from this map.Resets internal storage to empty state, allowing garbage collection of any existing storage structures.
-
hashCode
public int hashCode()Returns the hash code value for this map.The hash code of a map is defined as the sum of the hash codes of each entry in the map's entry set. This implementation ensures consistency with the `equals` method.
-
equals
Compares the specified object with this map for equality.Returns
true
if the given object is also a map and the two maps represent the same mappings. More formally, two mapsm1
andm2
are equal if:m1.entrySet().equals(m2.entrySet())
-
toString
Returns a string representation of this map.The string representation consists of a list of key-value mappings in the order returned by the map's
entrySet
iterator, enclosed in braces ("{}"
). Adjacent mappings are separated by the characters", "
(comma and space). Each key-value mapping is rendered as the key followed by an equals sign ("="
) followed by the associated value. -
keySet
Returns a Set view of the keys in this map.The set is backed by the map, so changes to the map are reflected in the set. Set supports element removal but not addition. Iterator supports concurrent modification detection.
-
values
Returns aCollection
view of the values contained in this map.The collection is backed by the map, so changes to the map are reflected in the collection, and vice versa. If the map is modified while an iteration over the collection is in progress (except through the iterators own
remove
operation), the results of the iteration are undefined. The collection supports element removal, which removes the corresponding mapping from the map. It does not support theadd
oraddAll
operations. -
entrySet
Returns aSet
view of the mappings contained in this map.Each element in the returned set is a
Map.Entry
. The set is backed by the map, so changes to the map are reflected in the set, and vice versa. If the map is modified while an iteration over the set is in progress (except through the iterators ownremove
operation, or through thesetValue
operation on a map entry returned by the iterator), the results of the iteration are undefined. The set supports element removal, which removes the corresponding mapping from the map. It does not support theadd
oraddAll
operations. -
minus
Deprecated. -
plus
Deprecated. -
getLogicalValueType
Returns the current storage state of this map.Possible states are: EMPTY (no entries), OBJECT (single value), ENTRY (single entry), MAP (backing map), or ARRAY (compact array storage). Used internally to determine appropriate operations for current state.
- Returns:
- the LogicalValueType enum representing current storage state
-
computeKeyHashCode
Computes hash code for map keys, handling special cases.For String keys, respects case sensitivity setting. Handles null keys, self-referential keys, and standard objects. Used for both map operations and entry hash codes.
- Parameters:
key
- the key to compute hash code for- Returns:
- the computed hash code for the key
-
computeValueHashCode
Computes hash code for map values, handling special cases.Handles null values and self-referential values (where value is this map). Used for both map operations and entry hash codes.
- Parameters:
value
- the value to compute hash code for- Returns:
- the computed hash code for the value
-
getSingleValueKey
Returns the designated key for optimized single-value storage.When map contains one entry with this key, value is stored directly. Default implementation returns "id". Override to customize.
- Returns:
- the key to use for optimized single-value storage
-
getNewMap
Creates the backing map instance when size exceeds compactSize.Default implementation returns HashMap. Override to provide different map implementation (e.g., TreeMap for sorted maps, LinkedHashMap for insertion ordered maps).
- Returns:
- new empty map instance for backing storage
-
isCaseInsensitive
protected boolean isCaseInsensitive()Determines if String keys are compared case-insensitively.Default implementation returns false (case-sensitive). Override to change String key comparison behavior. Affects key equality and sorting.
- Returns:
- true if String keys should be compared ignoring case, false otherwise
-
compactSize
protected int compactSize()Returns the threshold size for compact array storage.When size exceeds this value, switches to map storage. When size reduces to this value, returns to array storage. Default implementation returns 70.
- Returns:
- the maximum number of entries for compact array storage
-
getOrdering
Returns the ordering strategy for this map.Valid values include:
- Returns:
- the ordering strategy for this map
-
builder
Returns a builder for creating customized CompactMap instances.For detailed configuration options and examples, see
CompactMap.Builder
.Note: When method chaining directly from builder(), you may need to provide a type witness to help type inference:
// Type witness needed: CompactMap<String, Integer> map = CompactMap.<String, Integer>builder() .sortedOrder() .build(); // Alternative without type witness: Builder<String, Integer> builder = CompactMap.builder(); CompactMap<String, Integer> map = builder.sortedOrder().build();
- Type Parameters:
K
- the type of keys maintained by the mapV
- the type of mapped values- Returns:
- a new CompactMapBuilder instance
- See Also:
-