abstract class AbstractMapBasedMultimap<K,V> extends AbstractMultimap<K,V> implements java.io.Serializable
Multimap
interface. This class represents a multimap as a map
that associates each key with a collection of values. All methods of Multimap
are
supported, including those specified as optional in the interface.
To implement a multimap, a subclass must define the method createCollection()
, which
creates an empty collection of values for a key.
The multimap constructor takes a map that has a single entry for each distinct key. When you
insert a key-value pair with a key that isn't already in the multimap, AbstractMapBasedMultimap
calls createCollection()
to create the collection of values
for that key. The subclass should not call createCollection()
directly, and a new
instance should be created every time the method is called.
For example, the subclass could pass a TreeMap
during construction, and
createCollection()
could return a TreeSet
, in which case the
multimap's iterators would propagate through the keys and values in sorted order.
Keys and values may be null, as long as the underlying collection classes support null elements.
The collections created by createCollection()
may or may not allow duplicates. If the
collection, such as a Set
, does not support duplicates, an added key-value pair will
replace an existing pair with the same key and value, if such a pair is present. With collections
like List
that allow duplicates, the collection will keep the existing key-value pairs
while adding a new pair.
This class is not threadsafe when any concurrent operations update the multimap, even if the
underlying map and createCollection()
method return threadsafe classes. Concurrent read
operations will work correctly. To allow concurrent update operations, wrap your multimap with a
call to Multimaps.synchronizedMultimap(com.google.common.collect.Multimap<K, V>)
.
For serialization to work, the subclass must specify explicit readObject
and writeObject
methods.
Modifier and Type | Class and Description |
---|---|
private class |
AbstractMapBasedMultimap.AsMap |
private class |
AbstractMapBasedMultimap.Itr<T> |
private class |
AbstractMapBasedMultimap.KeySet |
(package private) class |
AbstractMapBasedMultimap.NavigableAsMap |
(package private) class |
AbstractMapBasedMultimap.NavigableKeySet |
private class |
AbstractMapBasedMultimap.RandomAccessWrappedList
List decorator that stays in sync with the multimap values for a key and supports rapid random
access.
|
private class |
AbstractMapBasedMultimap.SortedAsMap |
private class |
AbstractMapBasedMultimap.SortedKeySet |
(package private) class |
AbstractMapBasedMultimap.WrappedCollection
Collection decorator that stays in sync with the multimap values for a key.
|
(package private) class |
AbstractMapBasedMultimap.WrappedList
List decorator that stays in sync with the multimap values for a key.
|
(package private) class |
AbstractMapBasedMultimap.WrappedNavigableSet |
(package private) class |
AbstractMapBasedMultimap.WrappedSet
Set decorator that stays in sync with the multimap values for a key.
|
(package private) class |
AbstractMapBasedMultimap.WrappedSortedSet
SortedSet decorator that stays in sync with the multimap values for a key.
|
AbstractMultimap.Entries, AbstractMultimap.EntrySet, AbstractMultimap.Values
Modifier and Type | Field and Description |
---|---|
private java.util.Map<K,java.util.Collection<V>> |
map |
private static long |
serialVersionUID |
private int |
totalSize |
Modifier | Constructor and Description |
---|---|
protected |
AbstractMapBasedMultimap(java.util.Map<K,java.util.Collection<V>> map)
Creates a new multimap that uses the provided map.
|
Modifier and Type | Method and Description |
---|---|
(package private) java.util.Map<K,java.util.Collection<V>> |
backingMap() |
void |
clear()
Removes all key-value pairs from the multimap, leaving it empty.
|
boolean |
containsKey(java.lang.Object key)
Returns
true if this multimap contains at least one key-value pair with the key key . |
(package private) java.util.Map<K,java.util.Collection<V>> |
createAsMap() |
(package private) abstract java.util.Collection<V> |
createCollection()
Creates the collection of values for a single key.
|
(package private) java.util.Collection<V> |
createCollection(K key)
Creates the collection of values for an explicitly provided key.
|
(package private) java.util.Collection<java.util.Map.Entry<K,V>> |
createEntries() |
(package private) Multiset<K> |
createKeys() |
(package private) java.util.Set<K> |
createKeySet() |
(package private) java.util.Map<K,java.util.Collection<V>> |
createMaybeNavigableAsMap() |
(package private) java.util.Set<K> |
createMaybeNavigableKeySet() |
(package private) java.util.Collection<V> |
createUnmodifiableEmptyCollection()
Creates an unmodifiable, empty collection of values.
|
(package private) java.util.Collection<V> |
createValues() |
java.util.Collection<java.util.Map.Entry<K,V>> |
entries()
Returns a view collection of all key-value pairs contained in this multimap, as
Map.Entry
instances. |
(package private) java.util.Iterator<java.util.Map.Entry<K,V>> |
entryIterator()
Returns an iterator across all key-value map entries, used by
entries().iterator() and
values().iterator() . |
(package private) java.util.Spliterator<java.util.Map.Entry<K,V>> |
entrySpliterator() |
void |
forEach(java.util.function.BiConsumer<? super K,? super V> action)
Performs the given action for all key-value pairs contained in this multimap.
|
java.util.Collection<V> |
get(K key)
Returns a view collection of the values associated with
key in this multimap, if any. |
private java.util.Collection<V> |
getOrCreateCollection(K key) |
private static <E> java.util.Iterator<E> |
iteratorOrListIterator(java.util.Collection<E> collection) |
boolean |
put(K key,
V value)
Stores a key-value pair in this multimap.
|
java.util.Collection<V> |
removeAll(java.lang.Object key)
Removes all values associated with the key
key . |
private void |
removeValuesForKey(java.lang.Object key)
Removes all values for the provided key.
|
java.util.Collection<V> |
replaceValues(K key,
java.lang.Iterable<? extends V> values)
Stores a collection of values with the same key, replacing any existing values for that key.
|
(package private) void |
setMap(java.util.Map<K,java.util.Collection<V>> map)
Used during deserialization only.
|
int |
size()
Returns the number of key-value pairs in this multimap.
|
(package private) <E> java.util.Collection<E> |
unmodifiableCollectionSubclass(java.util.Collection<E> collection) |
(package private) java.util.Iterator<V> |
valueIterator() |
java.util.Collection<V> |
values()
Returns a view collection containing the value from each key-value pair contained in
this multimap, without collapsing duplicates (so
values().size() == size() ). |
(package private) java.util.Spliterator<V> |
valueSpliterator() |
(package private) java.util.Collection<V> |
wrapCollection(K key,
java.util.Collection<V> collection)
Generates a decorated collection that remains consistent with the values in the multimap for
the provided key.
|
(package private) java.util.List<V> |
wrapList(K key,
java.util.List<V> list,
AbstractMapBasedMultimap.WrappedCollection ancestor) |
asMap, containsEntry, containsValue, equals, hashCode, isEmpty, keys, keySet, putAll, putAll, remove, toString
private transient int totalSize
private static final long serialVersionUID
protected AbstractMapBasedMultimap(java.util.Map<K,java.util.Collection<V>> map)
map
- place to store the mapping from each key to its corresponding valuesjava.lang.IllegalArgumentException
- if map
is not emptyfinal void setMap(java.util.Map<K,java.util.Collection<V>> map)
java.util.Collection<V> createUnmodifiableEmptyCollection()
This is used in removeAll(java.lang.Object)
on an empty key.
abstract java.util.Collection<V> createCollection()
Collections with weak, soft, or phantom references are not supported. Each call to createCollection
should create a new instance.
The returned collection class determines whether duplicate key-value pairs are allowed.
java.util.Collection<V> createCollection(K key)
createCollection()
, which is the correct behavior for most implementations. The LinkedHashMultimap
class overrides it.key
- key to associate with values in the collectionpublic int size()
Multimap
Note: this method does not return the number of distinct keys in the multimap,
which is given by keySet().size()
or asMap().size()
. See the opening section of
the Multimap
class documentation for clarification.
public boolean containsKey(@CheckForNull java.lang.Object key)
Multimap
true
if this multimap contains at least one key-value pair with the key key
.containsKey
in interface Multimap<K,V>
public boolean put(K key, V value)
Multimap
Some multimap implementations allow duplicate key-value pairs, in which case put
always adds a new key-value pair and increases the multimap size by 1. Other implementations
prohibit duplicates, and storing a key-value pair that's already in the multimap has no effect.
public java.util.Collection<V> replaceValues(K key, java.lang.Iterable<? extends V> values)
If values
is empty, this is equivalent to removeAll(key)
.
The returned collection is immutable.
replaceValues
in interface Multimap<K,V>
replaceValues
in class AbstractMultimap<K,V>
public java.util.Collection<V> removeAll(@CheckForNull java.lang.Object key)
key
.
Once this method returns, key
will not be mapped to any values, so it will not
appear in Multimap.keySet()
, Multimap.asMap()
, or any other views.
The returned collection is immutable.
<E> java.util.Collection<E> unmodifiableCollectionSubclass(java.util.Collection<E> collection)
public void clear()
Multimap
public java.util.Collection<V> get(K key)
key
in this multimap, if any.
Note that when containsKey(key)
is false, this returns an empty collection, not null
.
Changes to the returned collection will update the underlying multimap, and vice versa.
The returned collection is not serializable.
java.util.Collection<V> wrapCollection(K key, java.util.Collection<V> collection)
final java.util.List<V> wrapList(K key, java.util.List<V> list, @CheckForNull AbstractMapBasedMultimap.WrappedCollection ancestor)
private static <E> java.util.Iterator<E> iteratorOrListIterator(java.util.Collection<E> collection)
java.util.Set<K> createKeySet()
createKeySet
in class AbstractMultimap<K,V>
final java.util.Set<K> createMaybeNavigableKeySet()
private void removeValuesForKey(@CheckForNull java.lang.Object key)
public java.util.Collection<V> values()
values().size() == size()
).
Changes to the returned collection will update the underlying multimap, and vice versa. However, adding to the returned collection is not possible.
The iterator generated by the returned collection traverses the values for one key, followed by the values of a second key, and so on.
java.util.Collection<V> createValues()
createValues
in class AbstractMultimap<K,V>
java.util.Iterator<V> valueIterator()
valueIterator
in class AbstractMultimap<K,V>
java.util.Spliterator<V> valueSpliterator()
valueSpliterator
in class AbstractMultimap<K,V>
Multiset<K> createKeys()
createKeys
in class AbstractMultimap<K,V>
public java.util.Collection<java.util.Map.Entry<K,V>> entries()
Map.Entry
instances.
Changes to the returned collection or the entries it contains will update the underlying multimap, and vice versa. However, adding to the returned collection is not possible.
The iterator generated by the returned collection traverses the values for one key, followed by the values of a second key, and so on.
Each entry is an immutable snapshot of a key-value mapping in the multimap, taken at the time the entry is returned by a method call to the collection or its iterator.
java.util.Collection<java.util.Map.Entry<K,V>> createEntries()
createEntries
in class AbstractMultimap<K,V>
java.util.Iterator<java.util.Map.Entry<K,V>> entryIterator()
entries().iterator()
and
values().iterator()
. The default behavior, which traverses the values for one key, the
values for a second key, and so on, suffices for most AbstractMapBasedMultimap
implementations.entryIterator
in class AbstractMultimap<K,V>
java.util.Spliterator<java.util.Map.Entry<K,V>> entrySpliterator()
entrySpliterator
in class AbstractMultimap<K,V>
public void forEach(java.util.function.BiConsumer<? super K,? super V> action)
Multimap
Multimap
implementation, actions will be performed in the order of
iteration of Multimap.entries()
. Exceptions thrown by the action are relayed to the caller.
To loop over all keys and their associated value collections, write Multimaps.asMap(multimap).forEach((key, valueCollection) -> action())
.
java.util.Map<K,java.util.Collection<V>> createAsMap()
createAsMap
in class AbstractMultimap<K,V>