@GwtCompatible(emulated=true) public final class MapMaker extends GenericMapMaker<java.lang.Object,java.lang.Object>
A builder of ConcurrentMap
instances having any combination of the following features:
Usage example:
ConcurrentMap<Request, Stopwatch> timers = new MapMaker()
.concurrencyLevel(4)
.weakKeys()
.makeMap();
These features are all optional; new MapMaker().makeMap()
returns a valid concurrent
map that behaves similarly to a ConcurrentHashMap
.
The returned map is implemented as a hash table with similar performance characteristics to
ConcurrentHashMap
. It supports all optional operations of the ConcurrentMap
interface. It does not permit null keys or values.
Note: by default, the returned map uses equality comparisons (the equals
method) to determine equality for keys or values. However, if weakKeys()
was
specified, the map uses identity (==
) comparisons instead for keys. Likewise, if weakValues()
or softValues()
was specified, the map uses identity comparisons for values.
The view collections of the returned map have weakly consistent iterators. This means
that they are safe for concurrent use, but if other threads modify the map after the iterator is
created, it is undefined which of these changes, if any, are reflected in that iterator. These
iterators never throw ConcurrentModificationException
.
If weakKeys()
, weakValues()
, or softValues()
are requested, it is
possible for a key or value present in the map to be reclaimed by the garbage collector. Entries
with reclaimed keys or values may be removed from the map on each map modification or on
occasional map accesses; such entries may be counted by Map.size()
, but will never be
visible to read or write operations. A partially-reclaimed entry is never exposed to the user.
Any Map.Entry
instance retrieved from the map's
entry set is a snapshot of that entry's state at the time of
retrieval; such entries do, however, support Map.Entry.setValue(V)
, which simply
calls Map.put(K, V)
on the entry's key.
The maps produced by MapMaker
are serializable, and the deserialized maps retain all
the configuration properties of the original map. During deserialization, if the original map had
used soft or weak references, the entries are reconstructed as they were, but it's not unlikely
they'll be quickly garbage-collected before they are ever accessed.
new MapMaker().weakKeys().makeMap()
is a recommended replacement for WeakHashMap
, but note that it compares keys using object identity whereas WeakHashMap
uses Object.equals(java.lang.Object)
.
Modifier and Type | Class and Description |
---|---|
(package private) static class |
MapMaker.ComputingMapAdapter<K,V>
Overrides get() to compute on demand.
|
(package private) static class |
MapMaker.NullComputingConcurrentMap<K,V>
Computes on retrieval and evicts the result.
|
(package private) static class |
MapMaker.NullConcurrentMap<K,V>
A map that is always empty and evicts on insertion.
|
(package private) static class |
MapMaker.RemovalCause
The reason why an entry was removed.
|
(package private) static interface |
MapMaker.RemovalListener<K,V>
An object that can receive a notification when an entry is removed from a map.
|
(package private) static class |
MapMaker.RemovalNotification<K,V>
A notification of the removal of a single entry.
|
GenericMapMaker.NullListener
Modifier and Type | Field and Description |
---|---|
(package private) int |
concurrencyLevel |
private static int |
DEFAULT_CONCURRENCY_LEVEL |
private static int |
DEFAULT_EXPIRATION_NANOS |
private static int |
DEFAULT_INITIAL_CAPACITY |
(package private) long |
expireAfterAccessNanos |
(package private) long |
expireAfterWriteNanos |
(package private) int |
initialCapacity |
(package private) Equivalence<java.lang.Object> |
keyEquivalence |
(package private) MapMakerInternalMap.Strength |
keyStrength |
(package private) int |
maximumSize |
(package private) MapMaker.RemovalCause |
nullRemovalCause |
(package private) Ticker |
ticker |
(package private) static int |
UNSET_INT |
(package private) boolean |
useCustomMap |
(package private) MapMakerInternalMap.Strength |
valueStrength |
removalListener
Constructor and Description |
---|
MapMaker()
Constructs a new
MapMaker instance with default settings, including strong keys, strong
values, and no automatic eviction of any kind. |
Modifier and Type | Method and Description |
---|---|
private void |
checkExpiration(long duration,
java.util.concurrent.TimeUnit unit) |
MapMaker |
concurrencyLevel(int concurrencyLevel)
Guides the allowed concurrency among update operations.
|
(package private) MapMaker |
expireAfterAccess(long duration,
java.util.concurrent.TimeUnit unit)
Deprecated.
Caching functionality in
MapMaker has been moved to
CacheBuilder , with expireAfterAccess(long, java.util.concurrent.TimeUnit) being
replaced by CacheBuilder.expireAfterAccess(long, java.util.concurrent.TimeUnit) . Note that
CacheBuilder is simply an enhanced API for an implementation which was branched
from MapMaker . |
(package private) MapMaker |
expireAfterWrite(long duration,
java.util.concurrent.TimeUnit unit)
Deprecated.
Caching functionality in
MapMaker has been moved to
CacheBuilder , with expireAfterWrite(long, java.util.concurrent.TimeUnit) being
replaced by CacheBuilder.expireAfterWrite(long, java.util.concurrent.TimeUnit) . Note that CacheBuilder is simply an enhanced API for an implementation which was branched from
MapMaker . |
(package private) int |
getConcurrencyLevel() |
(package private) long |
getExpireAfterAccessNanos() |
(package private) long |
getExpireAfterWriteNanos() |
(package private) int |
getInitialCapacity() |
(package private) Equivalence<java.lang.Object> |
getKeyEquivalence() |
(package private) MapMakerInternalMap.Strength |
getKeyStrength() |
(package private) Ticker |
getTicker() |
(package private) MapMakerInternalMap.Strength |
getValueStrength() |
MapMaker |
initialCapacity(int initialCapacity)
Sets the minimum total size for the internal hash tables.
|
(package private) MapMaker |
keyEquivalence(Equivalence<java.lang.Object> equivalence)
Sets a custom
Equivalence strategy for comparing keys. |
(package private) <K,V> java.util.concurrent.ConcurrentMap<K,V> |
makeComputingMap(Function<? super K,? extends V> computingFunction)
Deprecated.
Caching functionality in
MapMaker has been moved to
CacheBuilder , with makeComputingMap(com.google.common.base.Function<? super K, ? extends V>) being replaced
by CacheBuilder.build(com.google.common.cache.CacheLoader<? super K1, V1>) . See the
MapMaker
Migration Guide for more details. |
(package private) <K,V> MapMakerInternalMap<K,V> |
makeCustomMap()
Returns a MapMakerInternalMap for the benefit of internal callers that use features of
that class not exposed through ConcurrentMap.
|
<K,V> java.util.concurrent.ConcurrentMap<K,V> |
makeMap()
Builds a thread-safe map, without on-demand computation of values.
|
(package private) MapMaker |
maximumSize(int size)
Deprecated.
Caching functionality in
MapMaker has been moved to
CacheBuilder , with maximumSize being
replaced by CacheBuilder.maximumSize . Note that CacheBuilder is simply an enhanced API for an implementation which was branched from
MapMaker . |
(package private) <K,V> GenericMapMaker<K,V> |
removalListener(MapMaker.RemovalListener<K,V> listener)
Deprecated.
Caching functionality in
MapMaker has been moved to
CacheBuilder , with removalListener(com.google.common.collect.MapMaker.RemovalListener<K, V>) being
replaced by CacheBuilder.removalListener . Note that CacheBuilder is simply an enhanced API for an implementation which was branched from
MapMaker . |
(package private) MapMaker |
setKeyStrength(MapMakerInternalMap.Strength strength) |
(package private) MapMaker |
setValueStrength(MapMakerInternalMap.Strength strength) |
MapMaker |
softValues()
Deprecated.
Caching functionality in
MapMaker has been moved to CacheBuilder , with softValues() being replaced by CacheBuilder.softValues() . Note that CacheBuilder is simply
an enhanced API for an implementation which was branched from MapMaker . This
method is scheduled for removal in March 2015. |
java.lang.String |
toString()
Returns a string representation for this MapMaker instance.
|
MapMaker |
weakKeys()
Specifies that each key (not value) stored in the map should be wrapped in a
WeakReference (by default, strong references are used). |
MapMaker |
weakValues()
Specifies that each value (not key) stored in the map should be wrapped in a
WeakReference (by default, strong references are used). |
getRemovalListener
private static final int DEFAULT_INITIAL_CAPACITY
private static final int DEFAULT_CONCURRENCY_LEVEL
private static final int DEFAULT_EXPIRATION_NANOS
static final int UNSET_INT
boolean useCustomMap
int initialCapacity
int concurrencyLevel
int maximumSize
MapMakerInternalMap.Strength keyStrength
MapMakerInternalMap.Strength valueStrength
long expireAfterWriteNanos
long expireAfterAccessNanos
MapMaker.RemovalCause nullRemovalCause
Equivalence<java.lang.Object> keyEquivalence
Ticker ticker
public MapMaker()
MapMaker
instance with default settings, including strong keys, strong
values, and no automatic eviction of any kind.@GwtIncompatible(value="To be supported") MapMaker keyEquivalence(Equivalence<java.lang.Object> equivalence)
Equivalence
strategy for comparing keys.
By default, the map uses Equivalence.identity()
to determine key equality when weakKeys()
is specified, and Equivalence.equals()
otherwise. The only place this is
used is in Interners.WeakInterner
.
keyEquivalence
in class GenericMapMaker<java.lang.Object,java.lang.Object>
Equivalence<java.lang.Object> getKeyEquivalence()
public MapMaker initialCapacity(int initialCapacity)
60
, and the concurrency level is 8
, then eight segments are created, each
having a hash table of size eight. Providing a large enough estimate at construction time
avoids the need for expensive resizing operations later, but setting this value unnecessarily
high wastes memory.initialCapacity
in class GenericMapMaker<java.lang.Object,java.lang.Object>
java.lang.IllegalArgumentException
- if initialCapacity
is negativejava.lang.IllegalStateException
- if an initial capacity was already setint getInitialCapacity()
@Deprecated MapMaker maximumSize(int size)
MapMaker
has been moved to
CacheBuilder
, with maximumSize
being
replaced by CacheBuilder.maximumSize
. Note that CacheBuilder
is simply an enhanced API for an implementation which was branched from
MapMaker
.When size
is zero, elements can be successfully added to the map, but are evicted
immediately. This has the same effect as invoking expireAfterWrite
(0, unit)
or expireAfterAccess
(0,
unit)
. It can be useful in testing, or to disable caching temporarily without a code change.
Caching functionality in MapMaker
has been moved to
CacheBuilder
.
maximumSize
in class GenericMapMaker<java.lang.Object,java.lang.Object>
size
- the maximum size of the mapjava.lang.IllegalArgumentException
- if size
is negativejava.lang.IllegalStateException
- if a maximum size was already setpublic MapMaker concurrencyLevel(int concurrencyLevel)
Note: Prior to Guava release 9.0, the default was 16. It is possible the default will change again in the future. If you care about this value, you should always choose it explicitly.
concurrencyLevel
in class GenericMapMaker<java.lang.Object,java.lang.Object>
java.lang.IllegalArgumentException
- if concurrencyLevel
is nonpositivejava.lang.IllegalStateException
- if a concurrency level was already setint getConcurrencyLevel()
@GwtIncompatible(value="java.lang.ref.WeakReference") public MapMaker weakKeys()
WeakReference
(by default, strong references are used).
Warning: when this method is used, the resulting map will use identity (==
)
comparison to determine equality of keys, which is a technical violation of the Map
specification, and may not be what you expect.
weakKeys
in class GenericMapMaker<java.lang.Object,java.lang.Object>
java.lang.IllegalStateException
- if the key strength was already setWeakReference
MapMaker setKeyStrength(MapMakerInternalMap.Strength strength)
MapMakerInternalMap.Strength getKeyStrength()
@GwtIncompatible(value="java.lang.ref.WeakReference") public MapMaker weakValues()
WeakReference
(by default, strong references are used).
Weak values will be garbage collected once they are weakly reachable. This makes them a poor
candidate for caching; consider softValues()
instead.
Warning: when this method is used, the resulting map will use identity (==
)
comparison to determine equality of values. This technically violates the specifications of
the methods containsValue
,
remove(Object, Object)
and
replace(K, V, V)
, and may not be what you
expect.
weakValues
in class GenericMapMaker<java.lang.Object,java.lang.Object>
java.lang.IllegalStateException
- if the value strength was already setWeakReference
@Deprecated @GwtIncompatible(value="java.lang.ref.SoftReference") public MapMaker softValues()
MapMaker
has been moved to CacheBuilder
, with softValues()
being replaced by CacheBuilder.softValues()
. Note that CacheBuilder
is simply
an enhanced API for an implementation which was branched from MapMaker
. This
method is scheduled for removal in March 2015.SoftReference
(by default, strong references are used). Softly-referenced objects will
be garbage-collected in a globally least-recently-used manner, in response to memory
demand.
Warning: in most circumstances it is better to set a per-cache maximum size instead of using soft references. You should only use this method if you are well familiar with the practical consequences of soft references.
Warning: when this method is used, the resulting map will use identity (==
)
comparison to determine equality of values. This technically violates the specifications of
the methods containsValue
,
remove(Object, Object)
and
replace(K, V, V)
, and may not be what you
expect.
softValues
in class GenericMapMaker<java.lang.Object,java.lang.Object>
java.lang.IllegalStateException
- if the value strength was already setSoftReference
MapMaker setValueStrength(MapMakerInternalMap.Strength strength)
MapMakerInternalMap.Strength getValueStrength()
@Deprecated MapMaker expireAfterWrite(long duration, java.util.concurrent.TimeUnit unit)
MapMaker
has been moved to
CacheBuilder
, with expireAfterWrite(long, java.util.concurrent.TimeUnit)
being
replaced by CacheBuilder.expireAfterWrite(long, java.util.concurrent.TimeUnit)
. Note that CacheBuilder
is simply an enhanced API for an implementation which was branched from
MapMaker
.When duration
is zero, elements can be successfully added to the map, but are
evicted immediately. This has a very similar effect to invoking maximumSize
(0)
. It can be useful in testing, or to disable caching temporarily without
a code change.
Expired entries may be counted by Map.size()
, but will never be visible to read or
write operations. Expired entries are currently cleaned up during write operations, or during
occasional read operations in the absense of writes; though this behavior may change in the
future.
expireAfterWrite
in class GenericMapMaker<java.lang.Object,java.lang.Object>
duration
- the length of time after an entry is created that it should be automatically
removedunit
- the unit that duration
is expressed injava.lang.IllegalArgumentException
- if duration
is negativejava.lang.IllegalStateException
- if the time to live or time to idle was already setprivate void checkExpiration(long duration, java.util.concurrent.TimeUnit unit)
long getExpireAfterWriteNanos()
@Deprecated @GwtIncompatible(value="To be supported") MapMaker expireAfterAccess(long duration, java.util.concurrent.TimeUnit unit)
MapMaker
has been moved to
CacheBuilder
, with expireAfterAccess(long, java.util.concurrent.TimeUnit)
being
replaced by CacheBuilder.expireAfterAccess(long, java.util.concurrent.TimeUnit)
. Note that
CacheBuilder
is simply an enhanced API for an implementation which was branched
from MapMaker
.When duration
is zero, elements can be successfully added to the map, but are
evicted immediately. This has a very similar effect to invoking maximumSize
(0)
. It can be useful in testing, or to disable caching temporarily without
a code change.
Expired entries may be counted by Map.size()
, but will never be visible to read or
write operations. Expired entries are currently cleaned up during write operations, or during
occasional read operations in the absense of writes; though this behavior may change in the
future.
expireAfterAccess
in class GenericMapMaker<java.lang.Object,java.lang.Object>
duration
- the length of time after an entry is last accessed that it should be
automatically removedunit
- the unit that duration
is expressed injava.lang.IllegalArgumentException
- if duration
is negativejava.lang.IllegalStateException
- if the time to idle or time to live was already setlong getExpireAfterAccessNanos()
Ticker getTicker()
@Deprecated @GwtIncompatible(value="To be supported") <K,V> GenericMapMaker<K,V> removalListener(MapMaker.RemovalListener<K,V> listener)
MapMaker
has been moved to
CacheBuilder
, with removalListener(com.google.common.collect.MapMaker.RemovalListener<K, V>)
being
replaced by CacheBuilder.removalListener
. Note that CacheBuilder
is simply an enhanced API for an implementation which was branched from
MapMaker
.MapMaker
will notify
each time an entry is removed from the map by any means.
Each map built by this map maker after this method is called invokes the supplied listener
after removing an element for any reason (see removal causes in MapMaker.RemovalCause
). It will
invoke the listener during invocations of any of that map's public methods (even read-only
methods).
Important note: Instead of returning this as a MapMaker
instance,
this method returns GenericMapMaker<K, V>
. From this point on, either the original
reference or the returned reference may be used to complete configuration and build the map,
but only the "generic" one is type-safe. That is, it will properly prevent you from building
maps whose key or value types are incompatible with the types accepted by the listener already
provided; the MapMaker
type cannot do this. For best results, simply use the standard
method-chaining idiom, as illustrated in the documentation at top, configuring a MapMaker
and building your Map
all in a single statement.
Warning: if you ignore the above advice, and use this MapMaker
to build a map
or cache whose key or value type is incompatible with the listener, you will likely experience
a ClassCastException
at some undefined point in the future.
java.lang.IllegalStateException
- if a removal listener was already setpublic <K,V> java.util.concurrent.ConcurrentMap<K,V> makeMap()
MapMaker
instance, so it can be invoked again to create multiple
independent maps.
The bulk operations putAll
, equals
, and clear
are not guaranteed to
be performed atomically on the returned map. Additionally, size
and containsValue
are implemented as bulk read operations, and thus may fail to observe concurrent
writes.
makeMap
in class GenericMapMaker<java.lang.Object,java.lang.Object>
@GwtIncompatible(value="MapMakerInternalMap") <K,V> MapMakerInternalMap<K,V> makeCustomMap()
makeCustomMap
in class GenericMapMaker<java.lang.Object,java.lang.Object>
@Deprecated <K,V> java.util.concurrent.ConcurrentMap<K,V> makeComputingMap(Function<? super K,? extends V> computingFunction)
MapMaker
has been moved to
CacheBuilder
, with makeComputingMap(com.google.common.base.Function<? super K, ? extends V>)
being replaced
by CacheBuilder.build(com.google.common.cache.CacheLoader<? super K1, V1>)
. See the
MapMaker
Migration Guide for more details.Map.get(java.lang.Object)
either
returns an already-computed value for the given key, atomically computes it using the supplied
function, or, if another thread is currently computing the value for this key, simply waits for
that thread to finish and returns its computed value. Note that the function may be executed
concurrently by multiple threads, but only for distinct keys.
New code should use CacheBuilder
, which supports
statistics collection, introduces the
CacheLoader
interface for loading entries into the cache
(allowing checked exceptions to be thrown in the process), and more cleanly separates
computation from the cache's Map
view.
If an entry's value has not finished computing yet, query methods besides get
return
immediately as if an entry doesn't exist. In other words, an entry isn't externally visible
until the value's computation completes.
Map.get(java.lang.Object)
on the returned map will never return null
. It may throw:
NullPointerException
if the key is null or the computing function returns a null
result
ComputationException
if an exception was thrown by the computing function. If that
exception is already of type ComputationException
it is propagated directly; otherwise
it is wrapped.
Note: Callers of get
must ensure that the key argument is of type
K
. The get
method accepts Object
, so the key type is not checked at
compile time. Passing an object of a type other than K
can result in that object being
unsafely passed to the computing function as type K
, and unsafely stored in the map.
If Map.put(K, V)
is called before a computation completes, other threads waiting on the
computation will wake up and return the stored value.
This method does not alter the state of this MapMaker
instance, so it can be invoked
again to create multiple independent maps.
Insertion, removal, update, and access operations on the returned map safely execute
concurrently by multiple threads. Iterators on the returned map are weakly consistent,
returning elements reflecting the state of the map at some point at or since the creation of
the iterator. They do not throw ConcurrentModificationException
, and may proceed
concurrently with other operations.
The bulk operations putAll
, equals
, and clear
are not guaranteed to
be performed atomically on the returned map. Additionally, size
and containsValue
are implemented as bulk read operations, and thus may fail to observe concurrent
writes.
makeComputingMap
in class GenericMapMaker<java.lang.Object,java.lang.Object>
computingFunction
- the function used to compute new valuespublic java.lang.String toString()
toString
in class java.lang.Object