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
ConcurrentMap
with thread-safe operations. - Null Handling: Supports
null
keys andnull
values using sentinel objects (AbstractConcurrentNullSafeMap.NullSentinel
). - Customizable: Allows customization of the underlying
ConcurrentMap
through its constructor. - Standard Map Behavior: Adheres to the
Map
andConcurrentMap
contract, 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);
System.out.println(map.get(null)); // Outputs: nullKey
System.out.println(map.get("key")); // Outputs: null
Additional Notes
- Equality and HashCode: Ensures consistent behavior for equality and hash code computation
in compliance with the
Map
contract. - Thread Safety: The thread safety of this class is determined by the thread safety of the
underlying
ConcurrentMap
implementation. - Sentinel Objects: The
AbstractConcurrentNullSafeMap.NullSentinel.NULL_KEY
andAbstractConcurrentNullSafeMap.NullSentinel.NULL_VALUE
are used internally to masknull
keys 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
ConstructorsModifierConstructorDescriptionprotected
AbstractConcurrentNullSafeMap
(ConcurrentMap<Object, Object> internalMap) Constructs a new AbstractConcurrentNullSafeMap with the provided internal map. -
Method Summary
Modifier and TypeMethodDescriptionvoid
clear()
computeIfAbsent
(K key, Function<? super K, ? extends V> mappingFunction) boolean
containsKey
(Object key) boolean
containsValue
(Object value) entrySet()
boolean
Overrides the equals method to ensure proper comparison between two maps.getOrDefault
(Object key, V defaultValue) int
hashCode()
Overrides the hashCode method to ensure consistency with equals.boolean
isEmpty()
keySet()
protected Object
maskNullKey
(K key) protected Object
maskNullValue
(V value) void
putIfAbsent
(K key, V value) boolean
boolean
int
size()
toString()
Overrides the toString method to provide a string representation of the map.protected K
unmaskNullKey
(Object key) protected V
unmaskNullValue
(Object value) values()
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
Methods 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:
containsKey
in interfaceMap<K,
V>
-
containsValue
- Specified by:
containsValue
in interfaceMap<K,
V>
-
get
-
put
-
remove
-
putAll
-
clear
public void clear() -
getOrDefault
- Specified by:
getOrDefault
in interfaceConcurrentMap<K,
V> - Specified by:
getOrDefault
in interfaceMap<K,
V>
-
putIfAbsent
- Specified by:
putIfAbsent
in interfaceConcurrentMap<K,
V> - Specified by:
putIfAbsent
in interfaceMap<K,
V>
-
remove
-
replace
-
replace
-
computeIfAbsent
- Specified by:
computeIfAbsent
in interfaceConcurrentMap<K,
V> - Specified by:
computeIfAbsent
in 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).
-