public class CustomConcurrentHashMap extends java.util.AbstractMap
A java.util.ConcurrentMap
supporting user-defined
equivalence comparisons, soft, weak, or strong keys and values, and
user-supplied computational methods for setting and updating
values. In particular:
MappingFunctions
that may be
used in method CustomConcurrentHashMap.computeIfAbsent to atomically
establish a computed value, along with
RemappingFunctions
that can be used in method
CustomConcurrentHashMap.compute to atomically
replace values.
int
keys and/or values, that may be more space-efficient
identityMap = new CustomConcurrentHashMap<Person,Salary>
(STRONG, IDENTITY, STRONG, EQUALS, 0);
weakKeyMap = new CustomConcurrentHashMap<Person,Salary>
(WEAK, IDENTITY, STRONG, EQUALS, 0);
.weakKeys());
byNameMap = new CustomConcurrentHashMap<Person,Salary>
(STRONG,
new Equivalence<Person>() {
public boolean equal(Person k, Object x) {
return x instanceof Person && k.name.equals(((Person)x).name);
public int hash(Object x) {
return (x instanceof Person) ? ((Person)x).name.hashCode() : 0;
}
},
STRONG, EQUALS, 0);
}
The first usage above provides a replacement for java.util.IdentityHashMap, and the second a replacement for java.util.WeakHashMap, adding concurrency, asynchronous cleanup,
and identity-based equality for keys. The third usage
illustrates a map with a custom Equivalence that looks only at the
name field of a (fictional) Person class.
This class also includes nested class KeySet
that provides space-efficient Set views of maps, also supporting
method intern
, which may be of use in canonicalizing
elements.
When used with (Weak or Soft) Reference keys and/or values,
elements that have asynchronously become null
are
treated as absent from the map and (eventually) removed from maps
via a background thread common across all maps. Because of the
potential for asynchronous clearing of References, methods such as
containsValue
have weaker guarantees than you might
expect even in the absence of other explicitly concurrent
operations. For example containsValue(value)
may
return true even if value
is no longer available upon
return from the method.
When Equivalences other than equality are used, the returned
collections may violate the specifications of Map
and/or
Set
interfaces, which mandate the use of the
equals
method when comparing objects. The methods of this
class otherwise have properties similar to those of java.util.ConcurrentHashMap
under its default settings. To
adaptively maintain semantics and performance under varying
conditions, this class does not support load factor or
concurrency level parameters. This class does not permit null keys
or values. This class is serializable; however, serializing a map
that uses soft or weak references can give unpredictable results.
This class supports all optional operations of the ConcurrentMap
interface. It supports have weakly consistent
iteration: an iterator over one of the map's view collections
may reflect some, all or none of the changes made to the collection
after the iterator was created.
This class is a member of the Java Collections Framework.
- the type of keys maintained by this map
- the type of mapped valuesModifiers | Name | Description |
---|---|---|
static Equivalence<java.lang.Object> |
EQUALS |
An Equivalence object performing java.lang.Object#equals based comparisons and using java.lang.Object#hashCode hashing |
static Equivalence<java.lang.Object> |
IDENTITY |
An Equivalence object performing identity-based comparisons and using java.lang.System#identityHashCode for hashing |
private static java.lang.String |
INT_STRING |
Config string for int maps |
static int |
MAX_SEGMENT_CAPACITY |
|
static int |
MIN_SEGMENT_CAPACITY |
|
static int |
NSEGMENTS |
|
static int |
SEGMENT_BITS |
|
static int |
SEGMENT_MASK |
|
static int |
SEGMENT_SHIFT |
|
private static java.lang.String |
SELF_STRING |
Config string for self-map (Set view) refs |
static CustomConcurrentHashMap.Strength |
SOFT |
The strength of soft references |
static CustomConcurrentHashMap.Strength |
STRONG |
The strength of ordinary references |
static sun.misc.Unsafe |
UNSAFE |
|
static CustomConcurrentHashMap.Strength |
WEAK |
The strength of weak references |
java.util.Set<Map.Entry<K, V>> |
entrySet |
|
CustomConcurrentHashMap.NodeFactory |
factory |
The factory for this map |
int |
initialSegmentCapacity |
The initial size of Segment tables when they are first constructed |
Equivalence<? super K> |
keyEquivalence |
Equivalence object for keys |
java.util.Set<K> |
keySet |
|
static java.lang.ref.ReferenceQueue<java.lang.Object> |
refQueue |
|
CustomConcurrentHashMap.Segment[] |
segments |
The segments, each of which acts as a hash table |
static long |
segmentsBase |
|
static int |
segmentsShift |
|
private static long |
serialVersionUID |
|
static long |
tableBase |
|
static int |
tableShift |
|
Equivalence<? super V> |
valueEquivalence |
Equivalence object for values |
java.util.Collection<V> |
values |
Constructor and description |
---|
CustomConcurrentHashMap
() |
Type | Name and description |
---|---|
java.lang.Object |
CustomConcurrentHashMap(java.lang.String ks, Equivalence<? super K> keq, java.lang.String vs, Equivalence<? super V> veq, int expectedSize) Internal constructor to set factory, equivalences and segment capacities, and to create segments array. |
java.lang.Object |
CustomConcurrentHashMap(CustomConcurrentHashMap.Strength keyStrength, Equivalence<? super K> keyEquivalence, CustomConcurrentHashMap.Strength valueStrength, Equivalence<? super V> valueEquivalence, int expectedSize) Creates a new CustomConcurrentHashMap with the given parameters. |
java.lang.Object |
CustomConcurrentHashMap() Creates a new CustomConcurrentHashMap with strong keys and values, and equality-based equivalence. |
void |
clear() Removes all of the mappings from this map. |
V |
compute(K key, RemappingFunction<? super K, V> remappingFunction) Updates the mapping for the given key with the result of the given remappingFunction. |
V |
computeIfAbsent(K key, MappingFunction<? super K, ? extends V> mappingFunction) If the specified key is not already associated with a value, computes its value using the given mappingFunction, and if non-null, enters it into the map. |
boolean |
containsKey(java.lang.Object key) Returns true if this map contains a key equivalent to
the given key with respect to this map's key Equivalence. |
boolean |
containsValue(java.lang.Object value) Returns true if this map maps one or more keys to a
value equivalent to the given value with respect to this map's
value Equivalence. |
V |
doPut(K key, V value, boolean onlyIfNull) Shared implementation for put, putIfAbsent |
java.util.Set<Map.Entry<K, V>> |
entrySet() Returns a java.util.Set view of the mappings contained in this map. |
boolean |
equals(java.lang.Object o) Compares the specified object with this map for equality. |
CustomConcurrentHashMap.Node |
findNode(java.lang.Object key, int hash, CustomConcurrentHashMap.Segment seg) Returns node for key, or null if none. |
V |
get(java.lang.Object key) Returns the value associated with a key equivalent to the given key with respect to this map's key Equivalence, or null
if no such mapping exists. |
static java.lang.ref.ReferenceQueue<java.lang.Object> |
getReclamationQueue() Returns a queue that may be used as the ReferenceQueue argument to java.lang.ref.Reference constructors to arrange removal of reclaimed nodes from maps via a background thread. |
CustomConcurrentHashMap.Segment |
getSegmentForAdd(int hash) Returns the segment for possibly inserting into the table associated with given hash, constructing it if necessary. |
CustomConcurrentHashMap.Segment |
getSegmentForTraversal(int hash) Returns the segment for traversing table for key with given hash. |
private static sun.misc.Unsafe |
getUnsafe() Returns a sun.misc.Unsafe. |
int |
hashCode() Returns the sum of the hash codes of each entry in this map's entrySet() view, which in turn are the hash codes
computed using key and value Equivalences for this Map. |
boolean |
isEmpty() Returns true if this map contains no key-value mappings. |
CustomConcurrentHashMap.KeyIterator |
keyIterator() |
java.util.Set<K> |
keySet() Returns a java.util.Set view of the keys contained in this map. |
static CustomConcurrentHashMap<java.lang.Integer, java.lang.Integer> |
newIntKeyIntValueMap(int expectedSize) Returns a new map using Integer keys and values. |
static CustomConcurrentHashMap<java.lang.Integer, ValueType> |
newIntKeyMap(CustomConcurrentHashMap.Strength valueStrength, Equivalence<? super ValueType> valueEquivalence, int expectedSize) Returns a new map using Integer keys and the given value parameters. |
static CustomConcurrentHashMap<KeyType, java.lang.Integer> |
newIntValueMap(CustomConcurrentHashMap.Strength keyStrength, Equivalence<? super KeyType> keyEquivalence, int expectedSize) Returns a new map using the given key parameters and Integer values. |
V |
put(K key, V value) Maps the specified key to the specified value in this map. |
void |
putAll(java.util.Map<? extends K, ? extends V> m) Copies all of the mappings from the specified map to this one. |
V |
putIfAbsent(K key, V value) {@inheritDoc} |
private void |
readObject(java.io.ObjectInputStream s) Reconstitutes the instance from a stream (that is, deserializes it). |
V |
remove(java.lang.Object key) Removes the mapping for the specified key. |
boolean |
remove(java.lang.Object key, java.lang.Object value) {@inheritDoc} |
void |
removeIfReclaimed(CustomConcurrentHashMap.Node r) Removes node if its key or value are null. |
V |
replace(K key, V value) {@inheritDoc} |
boolean |
replace(K key, V oldValue, V newValue) {@inheritDoc} |
int |
size() Returns the number of key-value mappings in this map. |
static int |
spreadHash(int h) Applies a supplemental hash function to a given hashCode, which defends against poor quality hash functions. |
static java.lang.ref.ReferenceQueue<java.lang.Object> |
startReclamation() |
static void |
storeNode(CustomConcurrentHashMap.Node[] table, int i, CustomConcurrentHashMap.Node r) |
static void |
storeSegment(CustomConcurrentHashMap.Segment[] segs, int i, CustomConcurrentHashMap.Segment s) |
CustomConcurrentHashMap |
valueOf(java.lang.String name) Returns the enum constant of this type with the specified name. |
CustomConcurrentHashMap[] |
values() Returns an array containing the constants of this enum type, in the order they are declared. |
java.util.Collection<V> |
values() Returns a java.util.Collection view of the values contained in this map. |
private void |
writeObject(java.io.ObjectOutputStream s) Saves the state of the instance to a stream (i.e., serializes it). |
Methods inherited from class | Name |
---|---|
class java.util.AbstractMap |
java.util.AbstractMap#remove(java.lang.Object), java.util.AbstractMap#get(java.lang.Object), java.util.AbstractMap#put(java.lang.Object, java.lang.Object), java.util.AbstractMap#equals(java.lang.Object), java.util.AbstractMap#toString(), java.util.AbstractMap#values(), java.util.AbstractMap#hashCode(), java.util.AbstractMap#clear(), java.util.AbstractMap#isEmpty(), java.util.AbstractMap#size(), java.util.AbstractMap#entrySet(), java.util.AbstractMap#putAll(java.util.Map), java.util.AbstractMap#keySet(), java.util.AbstractMap#containsKey(java.lang.Object), java.util.AbstractMap#containsValue(java.lang.Object), java.util.AbstractMap#wait(), java.util.AbstractMap#wait(long, int), java.util.AbstractMap#wait(long), java.util.AbstractMap#getClass(), java.util.AbstractMap#notify(), java.util.AbstractMap#notifyAll(), java.util.AbstractMap#remove(java.lang.Object, java.lang.Object), java.util.AbstractMap#replace(java.lang.Object, java.lang.Object), java.util.AbstractMap#replace(java.lang.Object, java.lang.Object, java.lang.Object), java.util.AbstractMap#replaceAll(java.util.function.BiFunction), java.util.AbstractMap#putIfAbsent(java.lang.Object, java.lang.Object), java.util.AbstractMap#compute(java.lang.Object, java.util.function.BiFunction), java.util.AbstractMap#computeIfAbsent(java.lang.Object, java.util.function.Function), java.util.AbstractMap#computeIfPresent(java.lang.Object, java.util.function.BiFunction), java.util.AbstractMap#forEach(java.util.function.BiConsumer), java.util.AbstractMap#getOrDefault(java.lang.Object, java.lang.Object), java.util.AbstractMap#merge(java.lang.Object, java.lang.Object, java.util.function.BiFunction) |
class java.lang.Object |
java.lang.Object#wait(), java.lang.Object#wait(long, int), java.lang.Object#wait(long), java.lang.Object#equals(java.lang.Object), java.lang.Object#toString(), java.lang.Object#hashCode(), java.lang.Object#getClass(), java.lang.Object#notify(), java.lang.Object#notifyAll() |
An Equivalence object performing java.lang.Object#equals based comparisons and using java.lang.Object#hashCode hashing
An Equivalence object performing identity-based comparisons and using java.lang.System#identityHashCode for hashing
Config string for int maps
Config string for self-map (Set view) refs
The strength of soft references
The strength of ordinary references
The strength of weak references
The factory for this map
The initial size of Segment tables when they are first constructed
Equivalence object for keys
The segments, each of which acts as a hash table
Equivalence object for values
Internal constructor to set factory, equivalences and segment capacities, and to create segments array.
Creates a new CustomConcurrentHashMap with the given parameters.
keyStrength
- the strength for keyskeyEquivalence
- the Equivalence to use for keysvalueStrength
- the strength for valuesvalueEquivalence
- the Equivalence to use for valuesexpectedSize
- an estimate of the number of elements
that will be held in the map. If no estimate is known,
zero is an acceptable value.Creates a new CustomConcurrentHashMap with strong keys and values, and equality-based equivalence.
Removes all of the mappings from this map.
Updates the mapping for the given key with the result of the given remappingFunction. This is equivalent to
value = remappingFunction.remap(key, get(key)); if (value != null) return put(key, value): else return remove(key);except that the action is performed atomically. Some attempted operations on this map by other threads may be blocked while computation is in progress.
Sample Usage. A remapping function can be used to perform frequency counting of words using code such as:
map.compute(word, new RemappingFunction<String,Integer>() { public Integer remap(String k, Integer v) { return (v == null) ? 1 : v + 1; }});
null
if the computation returned null
key
- key with which the specified value is to be associatedremappingFunction
- the function to compute a valueIf the specified key is not already associated with a value, computes its value using the given mappingFunction, and if non-null, enters it into the map. This is equivalent to
if (map.containsKey(key)) return map.get(key); value = mappingFunction.map(key); if (value != null) return map.put(key, value); else return null;except that the action is performed atomically. Some attempted operations on this map by other threads may be blocked while computation is in progress. Because this function is invoked within atomicity control, the computation should be short and simple. The most common usage is to construct a new object serving as an initial mapped value, or memoized result.
null
if the computation
returned null
key
- key with which the specified value is to be associatedmappingFunction
- the function to compute a value Returns true
if this map contains a key equivalent to
the given key with respect to this map's key Equivalence.
true
if this map contains the specified keykey
- possible key Returns true
if this map maps one or more keys to a
value equivalent to the given value with respect to this map's
value Equivalence. Note: This method requires a full internal
traversal of the hash table, and so is much slower than method
containsKey
.
true
if this map maps one or more keys to the
specified valuevalue
- value whose presence in this map is to be testedShared implementation for put, putIfAbsent
Returns a java.util.Set view of the mappings contained in this map.
The set is backed by the map, so changes to the map are
reflected in the set, and vice-versa. The set supports element
removal, which removes the corresponding mapping from the map,
via the Iterator.remove
, Set.remove
,
removeAll
, retainAll
, and clear
operations. It does not support the add
or
addAll
operations.
The view's iterator
is a "weakly consistent" iterator
that will never throw java.util.ConcurrentModificationException,
and guarantees to traverse elements as they existed upon
construction of the iterator, and may (but is not guaranteed to)
reflect any modifications subsequent to construction.
Compares the specified object with this map for equality.
Returns true
if the given object is also a map of the
same size, holding keys that are equal using this Map's key
Equivalence, and which map to values that are equal according
to this Map's value equivalence.
true
if the specified object is equal to this mapo
- object to be compared for equality with this mapReturns node for key, or null if none.
Returns the value associated with a key equivalent to the given
key with respect to this map's key Equivalence, or null
if no such mapping exists.
null
if
there is no mappingkey
- possible keyReturns a queue that may be used as the ReferenceQueue argument to java.lang.ref.Reference constructors to arrange removal of reclaimed nodes from maps via a background thread.
Returns the segment for possibly inserting into the table associated with given hash, constructing it if necessary.
hash
- the hash code for the keyReturns the segment for traversing table for key with given hash.
hash
- the hash code for the keyReturns a sun.misc.Unsafe. Suitable for use in a 3rd party package. Replace with a simple call to Unsafe.getUnsafe when integrating into a jdk.
Returns the sum of the hash codes of each entry in this map's
entrySet()
view, which in turn are the hash codes
computed using key and value Equivalences for this Map.
Returns true
if this map contains no key-value mappings.
true
if this map contains no key-value mappings Returns a java.util.Set view of the keys contained in this map.
The set is backed by the map, so changes to the map are
reflected in the set, and vice-versa. The set supports element
removal, which removes the corresponding mapping from this map,
via the Iterator.remove
, Set.remove
,
removeAll
, retainAll
, and clear
operations. It does not support the add
or
addAll
operations.
The view's iterator
is a "weakly consistent" iterator
that will never throw java.util.ConcurrentModificationException,
and guarantees to traverse elements as they existed upon
construction of the iterator, and may (but is not guaranteed to)
reflect any modifications subsequent to construction.
Returns a new map using Integer keys and values.
expectedSize
- an estimate of the number of elements
that will be held in the map. If no estimate is known,
zero is an acceptable value.Returns a new map using Integer keys and the given value parameters.
valueStrength
- the strength for valuesvalueEquivalence
- the Equivalence to use for valuesexpectedSize
- an estimate of the number of elements
that will be held in the map. If no estimate is known,
zero is an acceptable value.Returns a new map using the given key parameters and Integer values.
keyStrength
- the strength for keyskeyEquivalence
- the Equivalence to use for keysexpectedSize
- an estimate of the number of elements
that will be held in the map. If no estimate is known,
zero is an acceptable value.Maps the specified key to the specified value in this map.
key
, or
null
if there was no mapping for key
key
- key with which the specified value is to be associatedvalue
- value to be associated with the specified keyCopies all of the mappings from the specified map to this one. These mappings replace any mappings that this map had for any of the keys currently in the specified map.
m
- mappings to be stored in this map{@inheritDoc}
null
if there was no mapping for the keyReconstitutes the instance from a stream (that is, deserializes it).
s
- the streamRemoves the mapping for the specified key.
key
, or
null
if there was no mapping for key
key
- the key to remove{@inheritDoc}
Removes node if its key or value are null.
{@inheritDoc}
{@inheritDoc}
null
if there was no mapping for the key Returns the number of key-value mappings in this map. If the
map contains more than Integer.MAX_VALUE
elements, returns
Integer.MAX_VALUE
.
Applies a supplemental hash function to a given hashCode, which defends against poor quality hash functions. This is critical because we use power-of-two length hash tables, that otherwise encounter collisions for hashCodes that do not differ in lower or upper bits.
Returns the enum constant of this type with the specified name.
Returns an array containing the constants of this enum type, in the order they are declared.
Returns a java.util.Collection 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. The collection
supports element removal, which removes the corresponding
mapping from this map, via the Iterator.remove
,
Collection.remove
, removeAll
,
retainAll
, and clear
operations. It does not
support the add
or addAll
operations.
The view's iterator
is a "weakly consistent" iterator
that will never throw java.util.ConcurrentModificationException,
and guarantees to traverse elements as they existed upon
construction of the iterator, and may (but is not guaranteed to)
reflect any modifications subsequent to construction.
Saves the state of the instance to a stream (i.e., serializes it).
s
- the streamCopyright © 2008–2014 Václav Pech. All Rights Reserved.