com.google.common.collect
Class MapMaker

java.lang.Object
  extended by com.google.common.collect.GenericMapMaker<Object,Object>
      extended by com.google.common.collect.MapMaker

@GwtCompatible(emulated=true)
public final class MapMaker
extends GenericMapMaker<Object,Object>

A ConcurrentMap builder, providing any combination of these features: soft or weak keys, soft or weak values, size-based evicition, timed expiration, and on-demand computation of values. Usage example:

   ConcurrentMap<Key, Graph> graphs = new MapMaker()
       .concurrencyLevel(4)
       .softKeys()
       .weakValues()
       .maximumSize(10000)
       .expireAfterWrite(10, TimeUnit.MINUTES)
       .makeComputingMap(
           new Function<Key, Graph>() {
             public Graph apply(Key key) {
               return createExpensiveGraph(key);
             }
           });
These features are all optional; new MapMaker().makeMap() returns a valid concurrent map that behaves exactly like 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() or softKeys() 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 returned map has 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 map after the iterator was created.

An entry whose key or value is reclaimed by the garbage collector immediately disappears from the map. (If the default settings of strong keys and strong values are used, this will never happen.) The client can never observe a partially-reclaimed entry. 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).

The maps produced by MapMaker are serializable, and the deserialized maps retain all the configuration properties of the original map. If the map uses soft or weak references, the entries will be reconstructed as they were, but there is no guarantee that the entries won't be immediately reclaimed.

new MapMaker().weakKeys().makeMap() can almost always be used as a drop-in replacement for WeakHashMap, adding concurrency, asynchronous cleanup, identity-based equality for keys, and great flexibility.

Since:
2 (imported from Google Collections Library)
Author:
Bob Lee, Kevin Bourrillion

Constructor Summary
MapMaker()
          Constructs a new MapMaker instance with default settings, including strong keys, strong values, and no automatic expiration.
 
Method Summary
 MapMaker concurrencyLevel(int concurrencyLevel)
          Guides the allowed concurrency among update operations.
<K,V> GenericMapMaker<K,V>
evictionListener(MapEvictionListener<K,V> listener)
          Specifies a listener instance, which all maps built using this MapMaker will notify each time an entry is evicted.
 MapMaker expiration(long duration, TimeUnit unit)
          Deprecated. use expireAfterWrite(long, java.util.concurrent.TimeUnit), which behaves exactly the same. This method is scheduled for deletion in July 2012.
 MapMaker expireAfterAccess(long duration, TimeUnit unit)
          Specifies that each entry should be automatically removed from the map once a fixed duration has passed since the entry's last read or write access.
 MapMaker expireAfterWrite(long duration, TimeUnit unit)
          Specifies that each entry should be automatically removed from the map once a fixed duration has passed since the entry's creation or replacement.
 MapMaker initialCapacity(int initialCapacity)
          Sets a custom initial capacity (defaults to 16).
<K,V> ConcurrentMap<K,V>
makeComputingMap(Function<? super K,? extends V> computingFunction)
          Builds a map that supports atomic, on-demand computation of values.
<K,V> ConcurrentMap<K,V>
makeMap()
          Builds a map, without on-demand computation of values.
 MapMaker maximumSize(int size)
          Specifies the maximum number of entries the map may contain.
 MapMaker softKeys()
          Specifies that each key (not value) stored in the map should be wrapped in a SoftReference (by default, strong references are used).
 MapMaker softValues()
          Specifies that each value (not key) stored in the map should be wrapped in a SoftReference (by default, strong references are used).
 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).
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

MapMaker

public MapMaker()
Constructs a new MapMaker instance with default settings, including strong keys, strong values, and no automatic expiration.

Method Detail

initialCapacity

public MapMaker initialCapacity(int initialCapacity)
Sets a custom initial capacity (defaults to 16). Resizing this or any other kind of hash table is a relatively slow operation, so, when possible, it is a good idea to provide estimates of expected table sizes.

Specified by:
initialCapacity in class GenericMapMaker<Object,Object>
Throws:
IllegalArgumentException - if initialCapacity is negative
IllegalStateException - if an initial capacity was already set

maximumSize

@Beta
public MapMaker maximumSize(int size)
Specifies the maximum number of entries the map may contain. While the number of entries in the map is not guaranteed to grow to the maximum, the map will attempt to make the best use of memory without exceeding the maximum number of entries. As the map size grows close to the maximum, the map will evict entries that are less likely to be used again. For example, the map may evict an entry because it hasn't been used recently or very often.

When size is zero, elements can be successfully added to the map, but are evicted immediately.

Specified by:
maximumSize in class GenericMapMaker<Object,Object>
Parameters:
size - the maximum size of the map
Throws:
IllegalArgumentException - if size is negative
IllegalStateException - if a maximum size was already set
Since:
8

concurrencyLevel

@GwtIncompatible(value="java.util.concurrent.ConcurrentHashMap concurrencyLevel")
public MapMaker concurrencyLevel(int concurrencyLevel)
Guides the allowed concurrency among update operations. Used as a hint for internal sizing. The table is internally partitioned to try to permit the indicated number of concurrent updates without contention. Because placement in hash tables is essentially random, the actual concurrency will vary. Ideally, you should choose a value to accommodate as many threads as will ever concurrently modify the table. Using a significantly higher value than you need can waste space and time, and a significantly lower value can lead to thread contention. But overestimates and underestimates within an order of magnitude do not usually have much noticeable impact. A value of one is appropriate when it is known that only one thread will modify and all others will only read. Defaults to 4.

Note: Prior to Guava release 09, 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.

Specified by:
concurrencyLevel in class GenericMapMaker<Object,Object>
Throws:
IllegalArgumentException - if concurrencyLevel is nonpositive
IllegalStateException - if a concurrency level was already set

weakKeys

@GwtIncompatible(value="java.lang.ref.WeakReference")
public MapMaker weakKeys()
Specifies that each key (not value) stored in the map should be wrapped in a WeakReference (by default, strong references are used).

Note: the map will use identity (==) comparison to determine equality of weak keys, which may not behave as you expect. For example, storing a key in the map and then attempting a lookup using a different but equals-equivalent key will always fail.

Specified by:
weakKeys in class GenericMapMaker<Object,Object>
Throws:
IllegalStateException - if the key strength was already set
See Also:
WeakReference

softKeys

@GwtIncompatible(value="java.lang.ref.SoftReference")
public MapMaker softKeys()
Specifies that each key (not value) stored in the map should be wrapped in a SoftReference (by default, strong references are used).

Note: the map will use identity (==) comparison to determine equality of soft keys, which may not behave as you expect. For example, storing a key in the map and then attempting a lookup using a different but equals-equivalent key will always fail.

Specified by:
softKeys in class GenericMapMaker<Object,Object>
Throws:
IllegalStateException - if the key strength was already set
See Also:
SoftReference

weakValues

@GwtIncompatible(value="java.lang.ref.WeakReference")
public MapMaker weakValues()
Specifies that each value (not key) stored in the map should be wrapped in a 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.

Note: the map will use identity (==) comparison to determine equality of weak values. This will notably impact the behavior of containsValue, remove(Object, Object), and replace(K, V, V).

Specified by:
weakValues in class GenericMapMaker<Object,Object>
Throws:
IllegalStateException - if the value strength was already set
See Also:
WeakReference

softValues

@GwtIncompatible(value="java.lang.ref.SoftReference")
public MapMaker softValues()
Specifies that each value (not key) stored in the map should be wrapped in a SoftReference (by default, strong references are used).

Soft values will be garbage collected in response to memory demand, and in a least-recently-used manner. This makes them a good candidate for caching.

Note: the map will use identity (==) comparison to determine equality of soft values. This will notably impact the behavior of containsValue, remove(Object, Object), and replace(K, V, V).

Specified by:
softValues in class GenericMapMaker<Object,Object>
Throws:
IllegalStateException - if the value strength was already set
See Also:
SoftReference

expiration

@Deprecated
public MapMaker expiration(long duration,
                                      TimeUnit unit)
Deprecated. use expireAfterWrite(long, java.util.concurrent.TimeUnit), which behaves exactly the same. This method is scheduled for deletion in July 2012.

Old name of expireAfterWrite(long, java.util.concurrent.TimeUnit).

Specified by:
expiration in class GenericMapMaker<Object,Object>

expireAfterWrite

@Beta
public MapMaker expireAfterWrite(long duration,
                                      TimeUnit unit)
Specifies that each entry should be automatically removed from the map once a fixed duration has passed since the entry's creation or replacement. Note that changing the value of an entry will reset its expiration time.

When duration is zero, elements can be successfully added to the map, but are evicted immediately.

Specified by:
expireAfterWrite in class GenericMapMaker<Object,Object>
Parameters:
duration - the length of time after an entry is created that it should be automatically removed
unit - the unit that duration is expressed in
Throws:
IllegalArgumentException - if duration is negative
IllegalStateException - if the time to live or time to idle was already set
Since:
8

expireAfterAccess

@Beta
@GwtIncompatible(value="To be supported")
public MapMaker expireAfterAccess(long duration,
                                                            TimeUnit unit)
Specifies that each entry should be automatically removed from the map once a fixed duration has passed since the entry's last read or write access.

When duration is zero, elements can be successfully added to the map, but are evicted immediately.

Specified by:
expireAfterAccess in class GenericMapMaker<Object,Object>
Parameters:
duration - the length of time after an entry is last accessed that it should be automatically removed
unit - the unit that duration is expressed in
Throws:
IllegalArgumentException - if duration is negative
IllegalStateException - if the time to idle or time to live was already set
Since:
8

evictionListener

@Beta
@GwtIncompatible(value="To be supported")
public <K,V> GenericMapMaker<K,V> evictionListener(MapEvictionListener<K,V> listener)
Specifies a listener instance, which all maps built using this MapMaker will notify each time an entry is evicted.

A map built by this map maker will invoke the supplied listener after it evicts an entry, whether it does so due to timed expiration, exceeding the maximum size, or discovering that the key or value has been reclaimed by the garbage collector. It will invoke the listener synchronously, during invocations of any of that map's public methods (even read-only methods). The listener will not be invoked on manual removal.

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 maps whose key or value types are incompatible with the listener, you will likely experience a ClassCastException at an undefined point in the future.

Throws:
IllegalStateException - if an eviction listener was already set
Since:
7

makeMap

public <K,V> ConcurrentMap<K,V> makeMap()
Builds a map, without on-demand computation of values. This method does not alter the state of this MapMaker instance, so it can be invoked again to create multiple independent maps.

Specified by:
makeMap in class GenericMapMaker<Object,Object>
Returns:
a serializable concurrent map having the requested features

makeComputingMap

public <K,V> ConcurrentMap<K,V> makeComputingMap(Function<? super K,? extends V> computingFunction)
Builds a map that supports atomic, on-demand computation of values. 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.

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:

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.

Specified by:
makeComputingMap in class GenericMapMaker<Object,Object>
Parameters:
computingFunction - the function used to compute new values
Returns:
a serializable concurrent map having the requested features

toString

public String toString()
Returns a string representation for this MapMaker instance. The form of this representation is not guaranteed.

Overrides:
toString in class Object
Returns:
a string representation of the object.