com.google.common.collect
Class Multimaps

java.lang.Object
  extended by com.google.common.collect.Multimaps

@GwtCompatible(emulated=true)
public final class Multimaps
extends Object

Provides static methods acting on or generating a Multimap.

Since:
2 (imported from Google Collections Library)
Author:
Jared Levy, Robert Konigsberg, Mike Bostock, Louis Wasserman

Method Summary
static
<K,V> SetMultimap<K,V>
forMap(Map<K,V> map)
          Returns a multimap view of the specified map.
static
<K,V> ImmutableListMultimap<K,V>
index(Iterable<V> values, Function<? super V,K> keyFunction)
          Creates an index ImmutableListMultimap that contains the results of applying a specified function to each item in an Iterable of values.
static
<K,V,M extends Multimap<K,V>>
M
invertFrom(Multimap<? extends V,? extends K> source, M dest)
          Copies each key-value mapping in source into dest, with its key and value reversed.
static
<K,V> ListMultimap<K,V>
newListMultimap(Map<K,Collection<V>> map, Supplier<? extends List<V>> factory)
          Creates a new ListMultimap that uses the provided map and factory.
static
<K,V> Multimap<K,V>
newMultimap(Map<K,Collection<V>> map, Supplier<? extends Collection<V>> factory)
          Creates a new Multimap that uses the provided map and factory.
static
<K,V> SetMultimap<K,V>
newSetMultimap(Map<K,Collection<V>> map, Supplier<? extends Set<V>> factory)
          Creates a new SetMultimap that uses the provided map and factory.
static
<K,V> SortedSetMultimap<K,V>
newSortedSetMultimap(Map<K,Collection<V>> map, Supplier<? extends SortedSet<V>> factory)
          Creates a new SortedSetMultimap that uses the provided map and factory.
static
<K,V> ListMultimap<K,V>
synchronizedListMultimap(ListMultimap<K,V> multimap)
          Returns a synchronized (thread-safe) ListMultimap backed by the specified multimap.
static
<K,V> Multimap<K,V>
synchronizedMultimap(Multimap<K,V> multimap)
          Returns a synchronized (thread-safe) multimap backed by the specified multimap.
static
<K,V> SetMultimap<K,V>
synchronizedSetMultimap(SetMultimap<K,V> multimap)
          Returns a synchronized (thread-safe) SetMultimap backed by the specified multimap.
static
<K,V> SortedSetMultimap<K,V>
synchronizedSortedSetMultimap(SortedSetMultimap<K,V> multimap)
          Returns a synchronized (thread-safe) SortedSetMultimap backed by the specified multimap.
static
<K,V1,V2> ListMultimap<K,V2>
transformEntries(ListMultimap<K,V1> fromMap, Maps.EntryTransformer<? super K,? super V1,V2> transformer)
          Returns a view of a ListMultimap whose values are derived from the original multimap's entries.
static
<K,V1,V2> Multimap<K,V2>
transformEntries(Multimap<K,V1> fromMap, Maps.EntryTransformer<? super K,? super V1,V2> transformer)
          Returns a view of a multimap whose values are derived from the original multimap's entries.
static
<K,V1,V2> ListMultimap<K,V2>
transformValues(ListMultimap<K,V1> fromMultimap, Function<? super V1,V2> function)
          Returns a view of a ListMultimap where each value is transformed by a function.
static
<K,V1,V2> Multimap<K,V2>
transformValues(Multimap<K,V1> fromMultimap, Function<? super V1,V2> function)
          Returns a view of a multimap where each value is transformed by a function.
static
<K,V> ListMultimap<K,V>
unmodifiableListMultimap(ListMultimap<K,V> delegate)
          Returns an unmodifiable view of the specified ListMultimap.
static
<K,V> Multimap<K,V>
unmodifiableMultimap(Multimap<K,V> delegate)
          Returns an unmodifiable view of the specified multimap.
static
<K,V> SetMultimap<K,V>
unmodifiableSetMultimap(SetMultimap<K,V> delegate)
          Returns an unmodifiable view of the specified SetMultimap.
static
<K,V> SortedSetMultimap<K,V>
unmodifiableSortedSetMultimap(SortedSetMultimap<K,V> delegate)
          Returns an unmodifiable view of the specified SortedSetMultimap.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Method Detail

newMultimap

public static <K,V> Multimap<K,V> newMultimap(Map<K,Collection<V>> map,
                                              Supplier<? extends Collection<V>> factory)
Creates a new Multimap that uses the provided map and factory. It can generate a multimap based on arbitrary Map and Collection classes.

The factory-generated and map classes determine the multimap iteration order. They also specify the behavior of the equals, hashCode, and toString methods for the multimap and its returned views. However, the multimap's get method returns instances of a different class than factory.get() does.

The multimap is serializable if map, factory, the collections generated by factory, and the multimap contents are all serializable.

The multimap is not threadsafe when any concurrent operations update the multimap, even if map and the instances generated by factory are. Concurrent read operations will work correctly. To allow concurrent update operations, wrap the multimap with a call to synchronizedMultimap(com.google.common.collect.Multimap).

Call this method only when the simpler methods ArrayListMultimap.create(), HashMultimap.create(), LinkedHashMultimap.create(), LinkedListMultimap.create(), TreeMultimap.create(), and TreeMultimap.create(Comparator, Comparator) won't suffice.

Note: the multimap assumes complete ownership over of map and the collections returned by factory. Those objects should not be manually updated and they should not use soft, weak, or phantom references.

Parameters:
map - place to store the mapping from each key to its corresponding values
factory - supplier of new, empty collections that will each hold all values for a given key
Throws:
IllegalArgumentException - if map is not empty

newListMultimap

public static <K,V> ListMultimap<K,V> newListMultimap(Map<K,Collection<V>> map,
                                                      Supplier<? extends List<V>> factory)
Creates a new ListMultimap that uses the provided map and factory. It can generate a multimap based on arbitrary Map and List classes.

The factory-generated and map classes determine the multimap iteration order. They also specify the behavior of the equals, hashCode, and toString methods for the multimap and its returned views. The multimap's get, removeAll, and replaceValues methods return RandomAccess lists if the factory does. However, the multimap's get method returns instances of a different class than does factory.get().

The multimap is serializable if map, factory, the lists generated by factory, and the multimap contents are all serializable.

The multimap is not threadsafe when any concurrent operations update the multimap, even if map and the instances generated by factory are. Concurrent read operations will work correctly. To allow concurrent update operations, wrap the multimap with a call to synchronizedListMultimap(com.google.common.collect.ListMultimap).

Call this method only when the simpler methods ArrayListMultimap.create() and LinkedListMultimap.create() won't suffice.

Note: the multimap assumes complete ownership over of map and the lists returned by factory. Those objects should not be manually updated and they should not use soft, weak, or phantom references.

Parameters:
map - place to store the mapping from each key to its corresponding values
factory - supplier of new, empty lists that will each hold all values for a given key
Throws:
IllegalArgumentException - if map is not empty

newSetMultimap

public static <K,V> SetMultimap<K,V> newSetMultimap(Map<K,Collection<V>> map,
                                                    Supplier<? extends Set<V>> factory)
Creates a new SetMultimap that uses the provided map and factory. It can generate a multimap based on arbitrary Map and Set classes.

The factory-generated and map classes determine the multimap iteration order. They also specify the behavior of the equals, hashCode, and toString methods for the multimap and its returned views. However, the multimap's get method returns instances of a different class than factory.get() does.

The multimap is serializable if map, factory, the sets generated by factory, and the multimap contents are all serializable.

The multimap is not threadsafe when any concurrent operations update the multimap, even if map and the instances generated by factory are. Concurrent read operations will work correctly. To allow concurrent update operations, wrap the multimap with a call to synchronizedSetMultimap(com.google.common.collect.SetMultimap).

Call this method only when the simpler methods HashMultimap.create(), LinkedHashMultimap.create(), TreeMultimap.create(), and TreeMultimap.create(Comparator, Comparator) won't suffice.

Note: the multimap assumes complete ownership over of map and the sets returned by factory. Those objects should not be manually updated and they should not use soft, weak, or phantom references.

Parameters:
map - place to store the mapping from each key to its corresponding values
factory - supplier of new, empty sets that will each hold all values for a given key
Throws:
IllegalArgumentException - if map is not empty

newSortedSetMultimap

public static <K,V> SortedSetMultimap<K,V> newSortedSetMultimap(Map<K,Collection<V>> map,
                                                                Supplier<? extends SortedSet<V>> factory)
Creates a new SortedSetMultimap that uses the provided map and factory. It can generate a multimap based on arbitrary Map and SortedSet classes.

The factory-generated and map classes determine the multimap iteration order. They also specify the behavior of the equals, hashCode, and toString methods for the multimap and its returned views. However, the multimap's get method returns instances of a different class than factory.get() does.

The multimap is serializable if map, factory, the sets generated by factory, and the multimap contents are all serializable.

The multimap is not threadsafe when any concurrent operations update the multimap, even if map and the instances generated by factory are. Concurrent read operations will work correctly. To allow concurrent update operations, wrap the multimap with a call to synchronizedSortedSetMultimap(com.google.common.collect.SortedSetMultimap).

Call this method only when the simpler methods TreeMultimap.create() and TreeMultimap.create(Comparator, Comparator) won't suffice.

Note: the multimap assumes complete ownership over of map and the sets returned by factory. Those objects should not be manually updated and they should not use soft, weak, or phantom references.

Parameters:
map - place to store the mapping from each key to its corresponding values
factory - supplier of new, empty sorted sets that will each hold all values for a given key
Throws:
IllegalArgumentException - if map is not empty

invertFrom

public static <K,V,M extends Multimap<K,V>> M invertFrom(Multimap<? extends V,? extends K> source,
                                                         M dest)
Copies each key-value mapping in source into dest, with its key and value reversed.

Parameters:
source - any multimap
dest - the multimap to copy into; usually empty
Returns:
dest

synchronizedMultimap

public static <K,V> Multimap<K,V> synchronizedMultimap(Multimap<K,V> multimap)
Returns a synchronized (thread-safe) multimap backed by the specified multimap. In order to guarantee serial access, it is critical that all access to the backing multimap is accomplished through the returned multimap.

It is imperative that the user manually synchronize on the returned multimap when accessing any of its collection views:

   Multimap<K, V> m = Multimaps.synchronizedMultimap(
       HashMultimap.<K, V>create());
   ...
   Set<K> s = m.keySet();  // Needn't be in synchronized block
   ...
   synchronized (m) {  // Synchronizing on m, not s!
     Iterator<K> i = s.iterator(); // Must be in synchronized block
     while (i.hasNext()) {
       foo(i.next());
     }
   }
Failure to follow this advice may result in non-deterministic behavior.

Note that the generated multimap's Multimap.removeAll(java.lang.Object) and Multimap.replaceValues(K, java.lang.Iterable) methods return collections that aren't synchronized.

The returned multimap will be serializable if the specified multimap is serializable.

Parameters:
multimap - the multimap to be wrapped in a synchronized view
Returns:
a synchronized view of the specified multimap

unmodifiableMultimap

public static <K,V> Multimap<K,V> unmodifiableMultimap(Multimap<K,V> delegate)
Returns an unmodifiable view of the specified multimap. Query operations on the returned multimap "read through" to the specified multimap, and attempts to modify the returned multimap, either directly or through the multimap's views, result in an UnsupportedOperationException.

Note that the generated multimap's Multimap.removeAll(java.lang.Object) and Multimap.replaceValues(K, java.lang.Iterable) methods return collections that are modifiable.

The returned multimap will be serializable if the specified multimap is serializable.

Parameters:
delegate - the multimap for which an unmodifiable view is to be returned
Returns:
an unmodifiable view of the specified multimap

synchronizedSetMultimap

public static <K,V> SetMultimap<K,V> synchronizedSetMultimap(SetMultimap<K,V> multimap)
Returns a synchronized (thread-safe) SetMultimap backed by the specified multimap.

You must follow the warnings described in synchronizedMultimap(com.google.common.collect.Multimap).

The returned multimap will be serializable if the specified multimap is serializable.

Parameters:
multimap - the multimap to be wrapped
Returns:
a synchronized view of the specified multimap

unmodifiableSetMultimap

public static <K,V> SetMultimap<K,V> unmodifiableSetMultimap(SetMultimap<K,V> delegate)
Returns an unmodifiable view of the specified SetMultimap. Query operations on the returned multimap "read through" to the specified multimap, and attempts to modify the returned multimap, either directly or through the multimap's views, result in an UnsupportedOperationException.

Note that the generated multimap's Multimap.removeAll(java.lang.Object) and Multimap.replaceValues(K, java.lang.Iterable) methods return collections that are modifiable.

The returned multimap will be serializable if the specified multimap is serializable.

Parameters:
delegate - the multimap for which an unmodifiable view is to be returned
Returns:
an unmodifiable view of the specified multimap

synchronizedSortedSetMultimap

public static <K,V> SortedSetMultimap<K,V> synchronizedSortedSetMultimap(SortedSetMultimap<K,V> multimap)
Returns a synchronized (thread-safe) SortedSetMultimap backed by the specified multimap.

You must follow the warnings described in synchronizedMultimap(com.google.common.collect.Multimap).

The returned multimap will be serializable if the specified multimap is serializable.

Parameters:
multimap - the multimap to be wrapped
Returns:
a synchronized view of the specified multimap

unmodifiableSortedSetMultimap

public static <K,V> SortedSetMultimap<K,V> unmodifiableSortedSetMultimap(SortedSetMultimap<K,V> delegate)
Returns an unmodifiable view of the specified SortedSetMultimap. Query operations on the returned multimap "read through" to the specified multimap, and attempts to modify the returned multimap, either directly or through the multimap's views, result in an UnsupportedOperationException.

Note that the generated multimap's Multimap.removeAll(java.lang.Object) and Multimap.replaceValues(K, java.lang.Iterable) methods return collections that are modifiable.

The returned multimap will be serializable if the specified multimap is serializable.

Parameters:
delegate - the multimap for which an unmodifiable view is to be returned
Returns:
an unmodifiable view of the specified multimap

synchronizedListMultimap

public static <K,V> ListMultimap<K,V> synchronizedListMultimap(ListMultimap<K,V> multimap)
Returns a synchronized (thread-safe) ListMultimap backed by the specified multimap.

You must follow the warnings described in synchronizedMultimap(com.google.common.collect.Multimap).

Parameters:
multimap - the multimap to be wrapped
Returns:
a synchronized view of the specified multimap

unmodifiableListMultimap

public static <K,V> ListMultimap<K,V> unmodifiableListMultimap(ListMultimap<K,V> delegate)
Returns an unmodifiable view of the specified ListMultimap. Query operations on the returned multimap "read through" to the specified multimap, and attempts to modify the returned multimap, either directly or through the multimap's views, result in an UnsupportedOperationException.

Note that the generated multimap's Multimap.removeAll(java.lang.Object) and Multimap.replaceValues(K, java.lang.Iterable) methods return collections that are modifiable.

The returned multimap will be serializable if the specified multimap is serializable.

Parameters:
delegate - the multimap for which an unmodifiable view is to be returned
Returns:
an unmodifiable view of the specified multimap

forMap

public static <K,V> SetMultimap<K,V> forMap(Map<K,V> map)
Returns a multimap view of the specified map. The multimap is backed by the map, so changes to the map are reflected in the multimap, and vice versa. If the map is modified while an iteration over one of the multimap's collection views is in progress (except through the iterator's own remove operation, or through the setValue operation on a map entry returned by the iterator), the results of the iteration are undefined.

The multimap supports mapping removal, which removes the corresponding mapping from the map. It does not support any operations which might add mappings, such as put, putAll or replaceValues.

The returned multimap will be serializable if the specified map is serializable.

Parameters:
map - the backing map for the returned multimap view

transformValues

@Beta
@GwtIncompatible(value="untested")
public static <K,V1,V2> Multimap<K,V2> transformValues(Multimap<K,V1> fromMultimap,
                                                                                 Function<? super V1,V2> function)
Returns a view of a multimap where each value is transformed by a function. All other properties of the multimap, such as iteration order, are left intact. For example, the code:
   Multimap<String, Integer> multimap =
     ImmutableSetMultimap.of("a", 2, "b", -3, "b", -3, "a", 4, "c", 6);
 Function<Integer, String> square = new Function<Integer, String>() {
     public String apply(Integer in) {
       return Integer.toString(in * in);
     }
 };
 Multimap<String, String> transformed =
     Multimaps.transformValues(multimap, square);
   System.out.println(transformed);
... prints {a=[4, 16], b=[9, 9], c=[6]}.

Changes in the underlying multimap are reflected in this view. Conversely, this view supports removal operations, and these are reflected in the underlying multimap.

It's acceptable for the underlying multimap to contain null keys, and even null values provided that the function is capable of accepting null input. The transformed multimap might contain null values, if the function sometimes gives a null result.

The returned multimap is not thread-safe or serializable, even if the underlying multimap is. The equals and hashCode methods of the returned multimap are meaningless, since there is not a definition of equals or hashCode for general collections, and get() will return a general Collection as opposed to a List or a Set.

The function is applied lazily, invoked when needed. This is necessary for the returned multimap to be a view, but it means that the function will be applied many times for bulk operations like Multimap.containsValue(java.lang.Object) and Multimap.toString(). For this to perform well, function should be fast. To avoid lazy evaluation when the returned multimap doesn't need to be a view, copy the returned multimap into a new multimap of your choosing.

Since:
7

transformEntries

@Beta
@GwtIncompatible(value="untested")
public static <K,V1,V2> Multimap<K,V2> transformEntries(Multimap<K,V1> fromMap,
                                                                                  Maps.EntryTransformer<? super K,? super V1,V2> transformer)
Returns a view of a multimap whose values are derived from the original multimap's entries. In contrast to transformValues(com.google.common.collect.Multimap, com.google.common.base.Function), this method's entry-transformation logic may depend on the key as well as the value.

All other properties of the transformed multimap, such as iteration order, are left intact. For example, the code:

   SetMultimap<String, Integer> multimap =
       ImmutableSetMultimap.of("a", 1, "a", 4, "b", -6);
   EntryTransformer<String, Integer, String> transformer =
       new EntryTransformer<String, Integer, String>() {
         public String transformEntry(String key, Integer value) {
            return (value >= 0) ? key : "no" + key;
         }
       };
   Multimap<String, String> transformed =
       Multimaps.transformEntries(multimap, transformer);
   System.out.println(transformed);
... prints {a=[a, a], b=[nob]}.

Changes in the underlying multimap are reflected in this view. Conversely, this view supports removal operations, and these are reflected in the underlying multimap.

It's acceptable for the underlying multimap to contain null keys and null values provided that the transformer is capable of accepting null inputs. The transformed multimap might contain null values if the transformer sometimes gives a null result.

The returned multimap is not thread-safe or serializable, even if the underlying multimap is. The equals and hashCode methods of the returned multimap are meaningless, since there is not a definition of equals or hashCode for general collections, and get() will return a general Collection as opposed to a List or a Set.

The transformer is applied lazily, invoked when needed. This is necessary for the returned multimap to be a view, but it means that the transformer will be applied many times for bulk operations like Multimap.containsValue(java.lang.Object) and Object.toString(). For this to perform well, transformer should be fast. To avoid lazy evaluation when the returned multimap doesn't need to be a view, copy the returned multimap into a new multimap of your choosing.

Warning: This method assumes that for any instance k of EntryTransformer key type K, k.equals(k2) implies that k2 is also of type K. Using an EntryTransformer key type for which this may not hold, such as ArrayList, may risk a ClassCastException when calling methods on the transformed multimap.

Since:
7

transformValues

@Beta
@GwtIncompatible(value="untested")
public static <K,V1,V2> ListMultimap<K,V2> transformValues(ListMultimap<K,V1> fromMultimap,
                                                                                     Function<? super V1,V2> function)
Returns a view of a ListMultimap where each value is transformed by a function. All other properties of the multimap, such as iteration order, are left intact. For example, the code:
   ListMultimap<String, Integer> multimap 
        = ImmutableListMultimap.of("a", 4, "a", 16, "b", 9);
   Function<Integer, Double> sqrt =
       new Function<Integer, Double>() {
         public Double apply(Integer in) {
           return Math.sqrt((int) in);
         }
       };
   ListMultimap<String, Double> transformed = Multimaps.transformValues(map,
       sqrt);
   System.out.println(transformed);
... prints {a=[2.0, 4.0], b=[3.0]}.

Changes in the underlying multimap are reflected in this view. Conversely, this view supports removal operations, and these are reflected in the underlying multimap.

It's acceptable for the underlying multimap to contain null keys, and even null values provided that the function is capable of accepting null input. The transformed multimap might contain null values, if the function sometimes gives a null result.

The returned multimap is not thread-safe or serializable, even if the underlying multimap is.

The function is applied lazily, invoked when needed. This is necessary for the returned multimap to be a view, but it means that the function will be applied many times for bulk operations like Multimap.containsValue(java.lang.Object) and Multimap.toString(). For this to perform well, function should be fast. To avoid lazy evaluation when the returned multimap doesn't need to be a view, copy the returned multimap into a new multimap of your choosing.

Since:
7

transformEntries

@Beta
@GwtIncompatible(value="untested")
public static <K,V1,V2> ListMultimap<K,V2> transformEntries(ListMultimap<K,V1> fromMap,
                                                                                      Maps.EntryTransformer<? super K,? super V1,V2> transformer)
Returns a view of a ListMultimap whose values are derived from the original multimap's entries. In contrast to transformValues(ListMultimap, Function), this method's entry-transformation logic may depend on the key as well as the value.

All other properties of the transformed multimap, such as iteration order, are left intact. For example, the code:

   Multimap<String, Integer> multimap =
       ImmutableMultimap.of("a", 1, "a", 4, "b", 6);
   EntryTransformer<String, Integer, String> transformer =
       new EntryTransformer<String, Integer, String>() {
         public String transformEntry(String key, Integer value) {
           return key + value;
         }
       };
   Multimap<String, String> transformed =
       Multimaps.transformEntries(multimap, transformer);
   System.out.println(transformed);
... prints {"a"=["a1", "a4"], "b"=["b6"]}.

Changes in the underlying multimap are reflected in this view. Conversely, this view supports removal operations, and these are reflected in the underlying multimap.

It's acceptable for the underlying multimap to contain null keys and null values provided that the transformer is capable of accepting null inputs. The transformed multimap might contain null values if the transformer sometimes gives a null result.

The returned multimap is not thread-safe or serializable, even if the underlying multimap is.

The transformer is applied lazily, invoked when needed. This is necessary for the returned multimap to be a view, but it means that the transformer will be applied many times for bulk operations like Multimap.containsValue(java.lang.Object) and Object.toString(). For this to perform well, transformer should be fast. To avoid lazy evaluation when the returned multimap doesn't need to be a view, copy the returned multimap into a new multimap of your choosing.

Warning: This method assumes that for any instance k of EntryTransformer key type K, k.equals(k2) implies that k2 is also of type K. Using an EntryTransformer key type for which this may not hold, such as ArrayList, may risk a ClassCastException when calling methods on the transformed multimap.

Since:
7

index

public static <K,V> ImmutableListMultimap<K,V> index(Iterable<V> values,
                                                     Function<? super V,K> keyFunction)
Creates an index ImmutableListMultimap that contains the results of applying a specified function to each item in an Iterable of values. Each value will be stored as a value in the resulting multimap, yielding a multimap with the same size as the input iterable. The key used to store that value in the multimap will be the result of calling the function on that value. The resulting multimap is created as an immutable snapshot. In the returned multimap, keys appear in the order they are first encountered, and the values corresponding to each key appear in the same order as they are encountered.

For example,

   List<String> badGuys =
       Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde");
   Function<String, Integer> stringLengthFunction = ...;
   Multimap<Integer, String> index =
       Multimaps.index(badGuys, stringLengthFunction);
   System.out.println(index);
prints
   {4=[Inky], 6=[Blinky], 5=[Pinky, Pinky, Clyde]}
The returned multimap is serializable if its keys and values are all serializable.

Parameters:
values - the values to use when constructing the ImmutableListMultimap
keyFunction - the function used to produce the key for each value
Returns:
ImmutableListMultimap mapping the result of evaluating the function keyFunction on each value in the input collection to that value
Throws:
NullPointerException - if any of the following cases is true:
  • values is null
  • keyFunction is null
  • An element in values is null
  • keyFunction returns null for any element of values