Class AbstractMapBasedMultimap<K,V>

java.lang.Object
com.google.common.collect.AbstractMultimap<K,V>
com.google.common.collect.AbstractMapBasedMultimap<K,V>
All Implemented Interfaces:
Multimap<K,V>, Serializable
Direct Known Subclasses:
AbstractListMultimap, AbstractSetMultimap, Multimaps.CustomMultimap

abstract class AbstractMapBasedMultimap<K,V> extends AbstractMultimap<K,V> implements Serializable
Basic implementation of the 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.

  • Field Details

    • map

      private transient Map<K,Collection<V>> map
    • totalSize

      private transient int totalSize
    • serialVersionUID

      private static final long serialVersionUID
      See Also:
  • Constructor Details

    • AbstractMapBasedMultimap

      protected AbstractMapBasedMultimap(Map<K,Collection<V>> map)
      Creates a new multimap that uses the provided map.
      Parameters:
      map - place to store the mapping from each key to its corresponding values
      Throws:
      IllegalArgumentException - if map is not empty
  • Method Details

    • setMap

      final void setMap(Map<K,Collection<V>> map)
      Used during deserialization only.
    • createUnmodifiableEmptyCollection

      Collection<V> createUnmodifiableEmptyCollection()
      Creates an unmodifiable, empty collection of values.

      This is used in removeAll(java.lang.Object) on an empty key.

    • createCollection

      abstract Collection<V> createCollection()
      Creates the collection of values for a single key.

      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.

      Returns:
      an empty collection of values
    • createCollection

      Collection<V> createCollection(K key)
      Creates the collection of values for an explicitly provided key. By default, it simply calls createCollection(), which is the correct behavior for most implementations. The LinkedHashMultimap class overrides it.
      Parameters:
      key - key to associate with values in the collection
      Returns:
      an empty collection of values
    • backingMap

      Map<K,Collection<V>> backingMap()
    • size

      public int size()
      Description copied from interface: Multimap
      Returns the number of key-value pairs in this 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.

      Specified by:
      size in interface Multimap<K,V>
    • containsKey

      public boolean containsKey(@CheckForNull Object key)
      Description copied from interface: Multimap
      Returns true if this multimap contains at least one key-value pair with the key key.
      Specified by:
      containsKey in interface Multimap<K,V>
    • put

      public boolean put(K key, V value)
      Description copied from interface: Multimap
      Stores a key-value pair in this 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.

      Specified by:
      put in interface Multimap<K,V>
      Overrides:
      put in class AbstractMultimap<K,V>
      Returns:
      true if the method increased the size of the multimap, or false if the multimap already contained the key-value pair and doesn't allow duplicates
    • getOrCreateCollection

      private Collection<V> getOrCreateCollection(K key)
    • replaceValues

      public Collection<V> replaceValues(K key, Iterable<? extends V> values)
      Stores a collection of values with the same key, replacing any existing values for that key.

      If values is empty, this is equivalent to removeAll(key).

      The returned collection is immutable.

      Specified by:
      replaceValues in interface Multimap<K,V>
      Overrides:
      replaceValues in class AbstractMultimap<K,V>
      Returns:
      the collection of replaced values, or an empty collection if no values were previously associated with the key. The collection may be modifiable, but updating it will have no effect on the multimap.
    • removeAll

      public Collection<V> removeAll(@CheckForNull Object key)
      Removes all values associated with the 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.

      Specified by:
      removeAll in interface Multimap<K,V>
      Returns:
      the values that were removed (possibly empty). The returned collection may be modifiable, but updating it will have no effect on the multimap.
    • unmodifiableCollectionSubclass

      <E> Collection<E> unmodifiableCollectionSubclass(Collection<E> collection)
    • clear

      public void clear()
      Description copied from interface: Multimap
      Removes all key-value pairs from the multimap, leaving it empty.
      Specified by:
      clear in interface Multimap<K,V>
    • get

      public Collection<V> get(K key)
      Returns a view collection of the values associated with 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.

      Specified by:
      get in interface Multimap<K,V>
    • wrapCollection

      Collection<V> wrapCollection(K key, Collection<V> collection)
      Generates a decorated collection that remains consistent with the values in the multimap for the provided key. Changes to the multimap may alter the returned collection, and vice versa.
    • wrapList

      final List<V> wrapList(K key, List<V> list, @CheckForNull AbstractMapBasedMultimap<K,V>.WrappedCollection ancestor)
    • iteratorOrListIterator

      private static <E> Iterator<E> iteratorOrListIterator(Collection<E> collection)
    • createKeySet

      Set<K> createKeySet()
      Specified by:
      createKeySet in class AbstractMultimap<K,V>
    • createMaybeNavigableKeySet

      final Set<K> createMaybeNavigableKeySet()
    • removeValuesForKey

      private void removeValuesForKey(@CheckForNull Object key)
      Removes all values for the provided key.
    • values

      public 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()).

      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.

      Specified by:
      values in interface Multimap<K,V>
      Overrides:
      values in class AbstractMultimap<K,V>
    • createValues

      Collection<V> createValues()
      Specified by:
      createValues in class AbstractMultimap<K,V>
    • valueIterator

      Iterator<V> valueIterator()
      Overrides:
      valueIterator in class AbstractMultimap<K,V>
    • valueSpliterator

      Spliterator<V> valueSpliterator()
      Overrides:
      valueSpliterator in class AbstractMultimap<K,V>
    • createKeys

      Multiset<K> createKeys()
      Specified by:
      createKeys in class AbstractMultimap<K,V>
    • entries

      public Collection<Map.Entry<K,V>> entries()
      Returns a view collection of all key-value pairs contained in this multimap, as 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.

      Specified by:
      entries in interface Multimap<K,V>
      Overrides:
      entries in class AbstractMultimap<K,V>
    • createEntries

      Collection<Map.Entry<K,V>> createEntries()
      Specified by:
      createEntries in class AbstractMultimap<K,V>
    • entryIterator

      Iterator<Map.Entry<K,V>> entryIterator()
      Returns an iterator across all key-value map entries, used by 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.
      Specified by:
      entryIterator in class AbstractMultimap<K,V>
      Returns:
      an iterator across map entries
    • entrySpliterator

      Spliterator<Map.Entry<K,V>> entrySpliterator()
      Overrides:
      entrySpliterator in class AbstractMultimap<K,V>
    • forEach

      public void forEach(BiConsumer<? super K,? super V> action)
      Description copied from interface: Multimap
      Performs the given action for all key-value pairs contained in this multimap. If an ordering is specified by the 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()).

      Specified by:
      forEach in interface Multimap<K,V>
    • createAsMap

      Map<K,Collection<V>> createAsMap()
      Specified by:
      createAsMap in class AbstractMultimap<K,V>
    • createMaybeNavigableAsMap

      final Map<K,Collection<V>> createMaybeNavigableAsMap()