Package com.cedarsoftware.util
Class AbstractConcurrentNullSafeMap<K,V>
java.lang.Object
com.cedarsoftware.util.AbstractConcurrentNullSafeMap<K,V>
- Type Parameters:
K- the type of keys maintained by this mapV- the type of mapped values
- All Implemented Interfaces:
ConcurrentMap<K,,V> Map<K,V>
- Direct Known Subclasses:
ConcurrentHashMapNullSafe,ConcurrentNavigableMapNullSafe
public abstract class AbstractConcurrentNullSafeMap<K,V>
extends Object
implements ConcurrentMap<K,V>
An abstract thread-safe implementation of the
ConcurrentMap interface that allows null keys
and null values. Internally, AbstractConcurrentNullSafeMap uses sentinel objects to
represent null keys and values, enabling safe handling of null while maintaining
compatibility with ConcurrentMap behavior.
Key Features
- Thread-Safe: Implements
ConcurrentMapwith thread-safe operations. - Null Handling: Supports
nullkeys andnullvalues using sentinel objects (AbstractConcurrentNullSafeMap.NullSentinel). - Customizable: Allows customization of the underlying
ConcurrentMapthrough its constructor. - Standard Map Behavior: Adheres to the
MapandConcurrentMapcontract, supporting operations likeputIfAbsent(K, V),computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>),merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>), and more.
Null Key and Value Handling
The AbstractConcurrentNullSafeMap uses internal sentinel objects (AbstractConcurrentNullSafeMap.NullSentinel) to distinguish
null keys and values from actual entries. This ensures that null keys and values can coexist
with regular entries without ambiguity.
Customization
This abstract class requires a concrete implementation of the backing ConcurrentMap.
To customize the behavior, subclasses can provide a specific implementation of the internal map.
Usage Example
// Example subclass using ConcurrentHashMap as the backing map
public class MyConcurrentNullSafeMap<K, V> extends AbstractConcurrentNullSafeMap<K, V> {
public MyConcurrentNullSafeMap() {
super(new ConcurrentHashMap<>());
}
}
// Using the map
MyConcurrentNullSafeMap<String, String> map = new MyConcurrentNullSafeMap<>();
map.put(null, "nullKey");
map.put("key", null);
LOG.info(map.get(null)); // Outputs: nullKey
LOG.info(map.get("key")); // Outputs: null
Additional Notes
- Equality and HashCode: Ensures consistent behavior for equality and hash code computation
in compliance with the
Mapcontract. - Thread Safety: The thread safety of this class is determined by the thread safety of the
underlying
ConcurrentMapimplementation. - Sentinel Objects: The
AbstractConcurrentNullSafeMap.NullSentinel.NULL_KEYandAbstractConcurrentNullSafeMap.NullSentinel.NULL_VALUEare used internally to masknullkeys and values.
- 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. - See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprotected static enum -
Field Summary
Fields -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedAbstractConcurrentNullSafeMap(ConcurrentMap<Object, Object> internalMap) Constructs a new AbstractConcurrentNullSafeMap with the provided internal map. -
Method Summary
Modifier and TypeMethodDescriptionvoidclear()computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) booleancontainsKey(Object key) booleancontainsValue(Object value) entrySet()booleanOverrides the equals method to ensure proper comparison between two maps.getOrDefault(Object key, V defaultValue) inthashCode()Overrides the hashCode method to ensure consistency with equals.booleanisEmpty()keySet()protected ObjectmaskNullKey(Object key) protected ObjectmaskNullValue(Object value) voidputIfAbsent(K key, V value) booleanbooleanintsize()toString()Overrides the toString method to provide a string representation of the map.protected KunmaskNullKey(Object key) protected VunmaskNullValue(Object value) values()Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, waitMethods inherited from interface java.util.concurrent.ConcurrentMap
computeIfPresent, forEach, replaceAll
-
Field Details
-
internalMap
-
-
Constructor Details
-
AbstractConcurrentNullSafeMap
Constructs a new AbstractConcurrentNullSafeMap with the provided internal map.- Parameters:
internalMap- the internal ConcurrentMap to use
-
-
Method Details
-
maskNullKey
-
unmaskNullKey
-
maskNullValue
-
unmaskNullValue
-
size
public int size() -
isEmpty
public boolean isEmpty() -
containsKey
- Specified by:
containsKeyin interfaceMap<K,V>
-
containsValue
- Specified by:
containsValuein interfaceMap<K,V>
-
get
-
put
-
remove
-
putAll
-
clear
public void clear() -
getOrDefault
- Specified by:
getOrDefaultin interfaceConcurrentMap<K,V> - Specified by:
getOrDefaultin interfaceMap<K,V>
-
putIfAbsent
- Specified by:
putIfAbsentin interfaceConcurrentMap<K,V> - Specified by:
putIfAbsentin interfaceMap<K,V>
-
remove
-
replace
-
replace
-
computeIfAbsent
- Specified by:
computeIfAbsentin interfaceConcurrentMap<K,V> - Specified by:
computeIfAbsentin interfaceMap<K,V>
-
compute
-
merge
-
values
-
keySet
-
entrySet
-
equals
Overrides the equals method to ensure proper comparison between two maps. Two maps are considered equal if they contain the same key-value mappings. -
hashCode
public int hashCode()Overrides the hashCode method to ensure consistency with equals. The hash code of a map is defined to be the sum of the hash codes of each entry in the map. -
toString
Overrides the toString method to provide a string representation of the map. The string representation consists of a list of key-value mappings in the order returned by the map's entrySet view's iterator, enclosed in braces ("{}"). Adjacent mappings are separated by the characters ", " (comma and space).
-