A builder of {@link ConcurrentMap} instances having any combination of the following features:
- keys or values automatically wrapped in {@linkplain WeakReference weak} or {@linkplain SoftReference soft} references
- least-recently-used eviction when a maximum size is exceeded
- time-based expiration of entries, measured since last access or last write
- notification of evicted (or otherwise removed) entries
- on-demand computation of values for keys not already present
Usage example:
{@code ConcurrentMap graphs = new MapMaker() .concurrencyLevel(4) .weakKeys() .maximumSize(10000) .expireAfterWrite(10, TimeUnit.MINUTES) .makeComputingMap(}new Function() public Graph apply(Key key) { return createExpensiveGraph(key); } });}
These features are all optional; {@code new MapMaker().makeMap()} returns a valid concurrent mapthat behaves similarly to a {@link ConcurrentHashMap}.
The returned map is implemented as a hash table with similar performance characteristics to {@link ConcurrentHashMap}. It supports all optional operations of the {@code ConcurrentMap}interface. It does not permit null keys or values.
Note: by default, the returned map uses equality comparisons (the {@link Object#equals equals} method) to determine equality for keys or values. However, if {@link #weakKeys} or {@link #softKeys} was specified, the map uses identity ({@code ==}) comparisons instead for keys. Likewise, if {@link #weakValues} or {@link #softValues} was specified, the map uses identitycomparisons 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 {@link ConcurrentModificationException}.
If soft or weak references were requested, it is possible for a key or value present in the the map to be reclaimed by the garbage collector. If this happens, the entry automatically disappears from the map. A partially-reclaimed entry is never exposed to the user. Any {@link java.util.Map.Entry} instance retrieved from the map's {@linkplain Map#entrySet entry set} is asnapshot of that entry's state at the time of retrieval; such entries do, however, support {@link java.util.Map.Entry#setValue}, which simply calls {@link Map#put} on the entry's key.
The maps produced by {@code MapMaker} are serializable, and the deserialized maps retain allthe 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.
{@code new MapMaker().weakKeys().makeMap()} is a recommended replacement for {@link java.util.WeakHashMap}, but note that it compares keys using object identity whereas {@code WeakHashMap} uses {@link Object#equals}.
@author Bob Lee
@author Charles Fry
@author Kevin Bourrillion
@since Guava release 02 (imported from Google Collections Library)