001/*
002 * Copyright (C) 2007 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.google.common.collect;
018
019import static com.google.common.base.Preconditions.checkNotNull;
020import static com.google.common.collect.CollectPreconditions.checkNonnegative;
021import static com.google.common.collect.CollectPreconditions.checkRemove;
022
023import com.google.common.annotations.Beta;
024import com.google.common.annotations.GwtCompatible;
025import com.google.common.annotations.GwtIncompatible;
026import com.google.common.base.Function;
027import com.google.common.base.Predicate;
028import com.google.common.base.Predicates;
029import com.google.common.base.Supplier;
030import com.google.common.collect.Maps.EntryTransformer;
031import com.google.errorprone.annotations.CanIgnoreReturnValue;
032import com.google.errorprone.annotations.concurrent.LazyInit;
033import com.google.j2objc.annotations.Weak;
034import com.google.j2objc.annotations.WeakOuter;
035import java.io.IOException;
036import java.io.ObjectInputStream;
037import java.io.ObjectOutputStream;
038import java.io.Serializable;
039import java.util.AbstractCollection;
040import java.util.Collection;
041import java.util.Collections;
042import java.util.Comparator;
043import java.util.HashSet;
044import java.util.Iterator;
045import java.util.List;
046import java.util.Map;
047import java.util.Map.Entry;
048import java.util.NavigableSet;
049import java.util.NoSuchElementException;
050import java.util.Set;
051import java.util.SortedSet;
052import java.util.Spliterator;
053import java.util.function.BiConsumer;
054import java.util.function.Consumer;
055import java.util.stream.Collector;
056import java.util.stream.Stream;
057import org.checkerframework.checker.nullness.qual.Nullable;
058
059/**
060 * Provides static methods acting on or generating a {@code Multimap}.
061 *
062 * <p>See the Guava User Guide article on <a href=
063 * "https://github.com/google/guava/wiki/CollectionUtilitiesExplained#multimaps"> {@code
064 * Multimaps}</a>.
065 *
066 * @author Jared Levy
067 * @author Robert Konigsberg
068 * @author Mike Bostock
069 * @author Louis Wasserman
070 * @since 2.0
071 */
072@GwtCompatible(emulated = true)
073public final class Multimaps {
074  private Multimaps() {}
075
076  /**
077   * Returns a {@code Collector} accumulating entries into a {@code Multimap} generated from the
078   * specified supplier. The keys and values of the entries are the result of applying the provided
079   * mapping functions to the input elements, accumulated in the encounter order of the stream.
080   *
081   * <p>Example:
082   *
083   * <pre>{@code
084   * static final ListMultimap<Character, String> FIRST_LETTER_MULTIMAP =
085   *     Stream.of("banana", "apple", "carrot", "asparagus", "cherry")
086   *         .collect(
087   *             toMultimap(
088   *                  str -> str.charAt(0),
089   *                  str -> str.substring(1),
090   *                  MultimapBuilder.treeKeys().arrayListValues()::build));
091   *
092   * // is equivalent to
093   *
094   * static final ListMultimap<Character, String> FIRST_LETTER_MULTIMAP;
095   *
096   * static {
097   *     FIRST_LETTER_MULTIMAP = MultimapBuilder.treeKeys().arrayListValues().build();
098   *     FIRST_LETTER_MULTIMAP.put('b', "anana");
099   *     FIRST_LETTER_MULTIMAP.put('a', "pple");
100   *     FIRST_LETTER_MULTIMAP.put('a', "sparagus");
101   *     FIRST_LETTER_MULTIMAP.put('c', "arrot");
102   *     FIRST_LETTER_MULTIMAP.put('c', "herry");
103   * }
104   * }</pre>
105   *
106   * @since 21.0
107   */
108  public static <T, K, V, M extends Multimap<K, V>> Collector<T, ?, M> toMultimap(
109      java.util.function.Function<? super T, ? extends K> keyFunction,
110      java.util.function.Function<? super T, ? extends V> valueFunction,
111      java.util.function.Supplier<M> multimapSupplier) {
112    return CollectCollectors.toMultimap(keyFunction, valueFunction, multimapSupplier);
113  }
114
115  /**
116   * Returns a {@code Collector} accumulating entries into a {@code Multimap} generated from the
117   * specified supplier. Each input element is mapped to a key and a stream of values, each of which
118   * are put into the resulting {@code Multimap}, in the encounter order of the stream and the
119   * encounter order of the streams of values.
120   *
121   * <p>Example:
122   *
123   * <pre>{@code
124   * static final ListMultimap<Character, Character> FIRST_LETTER_MULTIMAP =
125   *     Stream.of("banana", "apple", "carrot", "asparagus", "cherry")
126   *         .collect(
127   *             flatteningToMultimap(
128   *                  str -> str.charAt(0),
129   *                  str -> str.substring(1).chars().mapToObj(c -> (char) c),
130   *                  MultimapBuilder.linkedHashKeys().arrayListValues()::build));
131   *
132   * // is equivalent to
133   *
134   * static final ListMultimap<Character, Character> FIRST_LETTER_MULTIMAP;
135   *
136   * static {
137   *     FIRST_LETTER_MULTIMAP = MultimapBuilder.linkedHashKeys().arrayListValues().build();
138   *     FIRST_LETTER_MULTIMAP.putAll('b', Arrays.asList('a', 'n', 'a', 'n', 'a'));
139   *     FIRST_LETTER_MULTIMAP.putAll('a', Arrays.asList('p', 'p', 'l', 'e'));
140   *     FIRST_LETTER_MULTIMAP.putAll('c', Arrays.asList('a', 'r', 'r', 'o', 't'));
141   *     FIRST_LETTER_MULTIMAP.putAll('a', Arrays.asList('s', 'p', 'a', 'r', 'a', 'g', 'u', 's'));
142   *     FIRST_LETTER_MULTIMAP.putAll('c', Arrays.asList('h', 'e', 'r', 'r', 'y'));
143   * }
144   * }</pre>
145   *
146   * @since 21.0
147   */
148  @Beta
149  public static <T, K, V, M extends Multimap<K, V>> Collector<T, ?, M> flatteningToMultimap(
150      java.util.function.Function<? super T, ? extends K> keyFunction,
151      java.util.function.Function<? super T, ? extends Stream<? extends V>> valueFunction,
152      java.util.function.Supplier<M> multimapSupplier) {
153    return CollectCollectors.flatteningToMultimap(keyFunction, valueFunction, multimapSupplier);
154  }
155
156  /**
157   * Creates a new {@code Multimap} backed by {@code map}, whose internal value collections are
158   * generated by {@code factory}.
159   *
160   * <p><b>Warning: do not use</b> this method when the collections returned by {@code factory}
161   * implement either {@link List} or {@code Set}! Use the more specific method {@link
162   * #newListMultimap}, {@link #newSetMultimap} or {@link #newSortedSetMultimap} instead, to avoid
163   * very surprising behavior from {@link Multimap#equals}.
164   *
165   * <p>The {@code factory}-generated and {@code map} classes determine the multimap iteration
166   * order. They also specify the behavior of the {@code equals}, {@code hashCode}, and {@code
167   * toString} methods for the multimap and its returned views. However, the multimap's {@code get}
168   * method returns instances of a different class than {@code factory.get()} does.
169   *
170   * <p>The multimap is serializable if {@code map}, {@code factory}, the collections generated by
171   * {@code factory}, and the multimap contents are all serializable.
172   *
173   * <p>The multimap is not threadsafe when any concurrent operations update the multimap, even if
174   * {@code map} and the instances generated by {@code factory} are. Concurrent read operations will
175   * work correctly. To allow concurrent update operations, wrap the multimap with a call to {@link
176   * #synchronizedMultimap}.
177   *
178   * <p>Call this method only when the simpler methods {@link ArrayListMultimap#create()}, {@link
179   * HashMultimap#create()}, {@link LinkedHashMultimap#create()}, {@link
180   * LinkedListMultimap#create()}, {@link TreeMultimap#create()}, and {@link
181   * TreeMultimap#create(Comparator, Comparator)} won't suffice.
182   *
183   * <p>Note: the multimap assumes complete ownership over of {@code map} and the collections
184   * returned by {@code factory}. Those objects should not be manually updated and they should not
185   * use soft, weak, or phantom references.
186   *
187   * @param map place to store the mapping from each key to its corresponding values
188   * @param factory supplier of new, empty collections that will each hold all values for a given
189   *     key
190   * @throws IllegalArgumentException if {@code map} is not empty
191   */
192  public static <K, V> Multimap<K, V> newMultimap(
193      Map<K, Collection<V>> map, final Supplier<? extends Collection<V>> factory) {
194    return new CustomMultimap<>(map, factory);
195  }
196
197  private static class CustomMultimap<K, V> extends AbstractMapBasedMultimap<K, V> {
198    transient Supplier<? extends Collection<V>> factory;
199
200    CustomMultimap(Map<K, Collection<V>> map, Supplier<? extends Collection<V>> factory) {
201      super(map);
202      this.factory = checkNotNull(factory);
203    }
204
205    @Override
206    Set<K> createKeySet() {
207      return createMaybeNavigableKeySet();
208    }
209
210    @Override
211    Map<K, Collection<V>> createAsMap() {
212      return createMaybeNavigableAsMap();
213    }
214
215    @Override
216    protected Collection<V> createCollection() {
217      return factory.get();
218    }
219
220    @Override
221    <E> Collection<E> unmodifiableCollectionSubclass(Collection<E> collection) {
222      if (collection instanceof NavigableSet) {
223        return Sets.unmodifiableNavigableSet((NavigableSet<E>) collection);
224      } else if (collection instanceof SortedSet) {
225        return Collections.unmodifiableSortedSet((SortedSet<E>) collection);
226      } else if (collection instanceof Set) {
227        return Collections.unmodifiableSet((Set<E>) collection);
228      } else if (collection instanceof List) {
229        return Collections.unmodifiableList((List<E>) collection);
230      } else {
231        return Collections.unmodifiableCollection(collection);
232      }
233    }
234
235    @Override
236    Collection<V> wrapCollection(K key, Collection<V> collection) {
237      if (collection instanceof List) {
238        return wrapList(key, (List<V>) collection, null);
239      } else if (collection instanceof NavigableSet) {
240        return new WrappedNavigableSet(key, (NavigableSet<V>) collection, null);
241      } else if (collection instanceof SortedSet) {
242        return new WrappedSortedSet(key, (SortedSet<V>) collection, null);
243      } else if (collection instanceof Set) {
244        return new WrappedSet(key, (Set<V>) collection);
245      } else {
246        return new WrappedCollection(key, collection, null);
247      }
248    }
249
250    // can't use Serialization writeMultimap and populateMultimap methods since
251    // there's no way to generate the empty backing map.
252
253    /** @serialData the factory and the backing map */
254    @GwtIncompatible // java.io.ObjectOutputStream
255    private void writeObject(ObjectOutputStream stream) throws IOException {
256      stream.defaultWriteObject();
257      stream.writeObject(factory);
258      stream.writeObject(backingMap());
259    }
260
261    @GwtIncompatible // java.io.ObjectInputStream
262    @SuppressWarnings("unchecked") // reading data stored by writeObject
263    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
264      stream.defaultReadObject();
265      factory = (Supplier<? extends Collection<V>>) stream.readObject();
266      Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
267      setMap(map);
268    }
269
270    @GwtIncompatible // java serialization not supported
271    private static final long serialVersionUID = 0;
272  }
273
274  /**
275   * Creates a new {@code ListMultimap} that uses the provided map and factory. It can generate a
276   * multimap based on arbitrary {@link Map} and {@link List} classes.
277   *
278   * <p>The {@code factory}-generated and {@code map} classes determine the multimap iteration
279   * order. They also specify the behavior of the {@code equals}, {@code hashCode}, and {@code
280   * toString} methods for the multimap and its returned views. The multimap's {@code get}, {@code
281   * removeAll}, and {@code replaceValues} methods return {@code RandomAccess} lists if the factory
282   * does. However, the multimap's {@code get} method returns instances of a different class than
283   * does {@code factory.get()}.
284   *
285   * <p>The multimap is serializable if {@code map}, {@code factory}, the lists generated by {@code
286   * factory}, and the multimap contents are all serializable.
287   *
288   * <p>The multimap is not threadsafe when any concurrent operations update the multimap, even if
289   * {@code map} and the instances generated by {@code factory} are. Concurrent read operations will
290   * work correctly. To allow concurrent update operations, wrap the multimap with a call to {@link
291   * #synchronizedListMultimap}.
292   *
293   * <p>Call this method only when the simpler methods {@link ArrayListMultimap#create()} and {@link
294   * LinkedListMultimap#create()} won't suffice.
295   *
296   * <p>Note: the multimap assumes complete ownership over of {@code map} and the lists returned by
297   * {@code factory}. Those objects should not be manually updated, they should be empty when
298   * provided, and they should not use soft, weak, or phantom references.
299   *
300   * @param map place to store the mapping from each key to its corresponding values
301   * @param factory supplier of new, empty lists that will each hold all values for a given key
302   * @throws IllegalArgumentException if {@code map} is not empty
303   */
304  public static <K, V> ListMultimap<K, V> newListMultimap(
305      Map<K, Collection<V>> map, final Supplier<? extends List<V>> factory) {
306    return new CustomListMultimap<>(map, factory);
307  }
308
309  private static class CustomListMultimap<K, V> extends AbstractListMultimap<K, V> {
310    transient Supplier<? extends List<V>> factory;
311
312    CustomListMultimap(Map<K, Collection<V>> map, Supplier<? extends List<V>> factory) {
313      super(map);
314      this.factory = checkNotNull(factory);
315    }
316
317    @Override
318    Set<K> createKeySet() {
319      return createMaybeNavigableKeySet();
320    }
321
322    @Override
323    Map<K, Collection<V>> createAsMap() {
324      return createMaybeNavigableAsMap();
325    }
326
327    @Override
328    protected List<V> createCollection() {
329      return factory.get();
330    }
331
332    /** @serialData the factory and the backing map */
333    @GwtIncompatible // java.io.ObjectOutputStream
334    private void writeObject(ObjectOutputStream stream) throws IOException {
335      stream.defaultWriteObject();
336      stream.writeObject(factory);
337      stream.writeObject(backingMap());
338    }
339
340    @GwtIncompatible // java.io.ObjectInputStream
341    @SuppressWarnings("unchecked") // reading data stored by writeObject
342    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
343      stream.defaultReadObject();
344      factory = (Supplier<? extends List<V>>) stream.readObject();
345      Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
346      setMap(map);
347    }
348
349    @GwtIncompatible // java serialization not supported
350    private static final long serialVersionUID = 0;
351  }
352
353  /**
354   * Creates a new {@code SetMultimap} that uses the provided map and factory. It can generate a
355   * multimap based on arbitrary {@link Map} and {@link Set} classes.
356   *
357   * <p>The {@code factory}-generated and {@code map} classes determine the multimap iteration
358   * order. They also specify the behavior of the {@code equals}, {@code hashCode}, and {@code
359   * toString} methods for the multimap and its returned views. However, the multimap's {@code get}
360   * method returns instances of a different class than {@code factory.get()} does.
361   *
362   * <p>The multimap is serializable if {@code map}, {@code factory}, the sets generated by {@code
363   * factory}, and the multimap contents are all serializable.
364   *
365   * <p>The multimap is not threadsafe when any concurrent operations update the multimap, even if
366   * {@code map} and the instances generated by {@code factory} are. Concurrent read operations will
367   * work correctly. To allow concurrent update operations, wrap the multimap with a call to {@link
368   * #synchronizedSetMultimap}.
369   *
370   * <p>Call this method only when the simpler methods {@link HashMultimap#create()}, {@link
371   * LinkedHashMultimap#create()}, {@link TreeMultimap#create()}, and {@link
372   * TreeMultimap#create(Comparator, Comparator)} won't suffice.
373   *
374   * <p>Note: the multimap assumes complete ownership over of {@code map} and the sets returned by
375   * {@code factory}. Those objects should not be manually updated and they should not use soft,
376   * weak, or phantom references.
377   *
378   * @param map place to store the mapping from each key to its corresponding values
379   * @param factory supplier of new, empty sets that will each hold all values for a given key
380   * @throws IllegalArgumentException if {@code map} is not empty
381   */
382  public static <K, V> SetMultimap<K, V> newSetMultimap(
383      Map<K, Collection<V>> map, final Supplier<? extends Set<V>> factory) {
384    return new CustomSetMultimap<>(map, factory);
385  }
386
387  private static class CustomSetMultimap<K, V> extends AbstractSetMultimap<K, V> {
388    transient Supplier<? extends Set<V>> factory;
389
390    CustomSetMultimap(Map<K, Collection<V>> map, Supplier<? extends Set<V>> factory) {
391      super(map);
392      this.factory = checkNotNull(factory);
393    }
394
395    @Override
396    Set<K> createKeySet() {
397      return createMaybeNavigableKeySet();
398    }
399
400    @Override
401    Map<K, Collection<V>> createAsMap() {
402      return createMaybeNavigableAsMap();
403    }
404
405    @Override
406    protected Set<V> createCollection() {
407      return factory.get();
408    }
409
410    @Override
411    <E> Collection<E> unmodifiableCollectionSubclass(Collection<E> collection) {
412      if (collection instanceof NavigableSet) {
413        return Sets.unmodifiableNavigableSet((NavigableSet<E>) collection);
414      } else if (collection instanceof SortedSet) {
415        return Collections.unmodifiableSortedSet((SortedSet<E>) collection);
416      } else {
417        return Collections.unmodifiableSet((Set<E>) collection);
418      }
419    }
420
421    @Override
422    Collection<V> wrapCollection(K key, Collection<V> collection) {
423      if (collection instanceof NavigableSet) {
424        return new WrappedNavigableSet(key, (NavigableSet<V>) collection, null);
425      } else if (collection instanceof SortedSet) {
426        return new WrappedSortedSet(key, (SortedSet<V>) collection, null);
427      } else {
428        return new WrappedSet(key, (Set<V>) collection);
429      }
430    }
431
432    /** @serialData the factory and the backing map */
433    @GwtIncompatible // java.io.ObjectOutputStream
434    private void writeObject(ObjectOutputStream stream) throws IOException {
435      stream.defaultWriteObject();
436      stream.writeObject(factory);
437      stream.writeObject(backingMap());
438    }
439
440    @GwtIncompatible // java.io.ObjectInputStream
441    @SuppressWarnings("unchecked") // reading data stored by writeObject
442    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
443      stream.defaultReadObject();
444      factory = (Supplier<? extends Set<V>>) stream.readObject();
445      Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
446      setMap(map);
447    }
448
449    @GwtIncompatible // not needed in emulated source
450    private static final long serialVersionUID = 0;
451  }
452
453  /**
454   * Creates a new {@code SortedSetMultimap} that uses the provided map and factory. It can generate
455   * a multimap based on arbitrary {@link Map} and {@link SortedSet} classes.
456   *
457   * <p>The {@code factory}-generated and {@code map} classes determine the multimap iteration
458   * order. They also specify the behavior of the {@code equals}, {@code hashCode}, and {@code
459   * toString} methods for the multimap and its returned views. However, the multimap's {@code get}
460   * method returns instances of a different class than {@code factory.get()} does.
461   *
462   * <p>The multimap is serializable if {@code map}, {@code factory}, the sets generated by {@code
463   * factory}, and the multimap contents are all serializable.
464   *
465   * <p>The multimap is not threadsafe when any concurrent operations update the multimap, even if
466   * {@code map} and the instances generated by {@code factory} are. Concurrent read operations will
467   * work correctly. To allow concurrent update operations, wrap the multimap with a call to {@link
468   * #synchronizedSortedSetMultimap}.
469   *
470   * <p>Call this method only when the simpler methods {@link TreeMultimap#create()} and {@link
471   * TreeMultimap#create(Comparator, Comparator)} won't suffice.
472   *
473   * <p>Note: the multimap assumes complete ownership over of {@code map} and the sets returned by
474   * {@code factory}. Those objects should not be manually updated and they should not use soft,
475   * weak, or phantom references.
476   *
477   * @param map place to store the mapping from each key to its corresponding values
478   * @param factory supplier of new, empty sorted sets that will each hold all values for a given
479   *     key
480   * @throws IllegalArgumentException if {@code map} is not empty
481   */
482  public static <K, V> SortedSetMultimap<K, V> newSortedSetMultimap(
483      Map<K, Collection<V>> map, final Supplier<? extends SortedSet<V>> factory) {
484    return new CustomSortedSetMultimap<>(map, factory);
485  }
486
487  private static class CustomSortedSetMultimap<K, V> extends AbstractSortedSetMultimap<K, V> {
488    transient Supplier<? extends SortedSet<V>> factory;
489    transient Comparator<? super V> valueComparator;
490
491    CustomSortedSetMultimap(Map<K, Collection<V>> map, Supplier<? extends SortedSet<V>> factory) {
492      super(map);
493      this.factory = checkNotNull(factory);
494      valueComparator = factory.get().comparator();
495    }
496
497    @Override
498    Set<K> createKeySet() {
499      return createMaybeNavigableKeySet();
500    }
501
502    @Override
503    Map<K, Collection<V>> createAsMap() {
504      return createMaybeNavigableAsMap();
505    }
506
507    @Override
508    protected SortedSet<V> createCollection() {
509      return factory.get();
510    }
511
512    @Override
513    public Comparator<? super V> valueComparator() {
514      return valueComparator;
515    }
516
517    /** @serialData the factory and the backing map */
518    @GwtIncompatible // java.io.ObjectOutputStream
519    private void writeObject(ObjectOutputStream stream) throws IOException {
520      stream.defaultWriteObject();
521      stream.writeObject(factory);
522      stream.writeObject(backingMap());
523    }
524
525    @GwtIncompatible // java.io.ObjectInputStream
526    @SuppressWarnings("unchecked") // reading data stored by writeObject
527    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
528      stream.defaultReadObject();
529      factory = (Supplier<? extends SortedSet<V>>) stream.readObject();
530      valueComparator = factory.get().comparator();
531      Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
532      setMap(map);
533    }
534
535    @GwtIncompatible // not needed in emulated source
536    private static final long serialVersionUID = 0;
537  }
538
539  /**
540   * Copies each key-value mapping in {@code source} into {@code dest}, with its key and value
541   * reversed.
542   *
543   * <p>If {@code source} is an {@link ImmutableMultimap}, consider using {@link
544   * ImmutableMultimap#inverse} instead.
545   *
546   * @param source any multimap
547   * @param dest the multimap to copy into; usually empty
548   * @return {@code dest}
549   */
550  @CanIgnoreReturnValue
551  public static <K, V, M extends Multimap<K, V>> M invertFrom(
552      Multimap<? extends V, ? extends K> source, M dest) {
553    checkNotNull(dest);
554    for (Map.Entry<? extends V, ? extends K> entry : source.entries()) {
555      dest.put(entry.getValue(), entry.getKey());
556    }
557    return dest;
558  }
559
560  /**
561   * Returns a synchronized (thread-safe) multimap backed by the specified multimap. In order to
562   * guarantee serial access, it is critical that <b>all</b> access to the backing multimap is
563   * accomplished through the returned multimap.
564   *
565   * <p>It is imperative that the user manually synchronize on the returned multimap when accessing
566   * any of its collection views:
567   *
568   * <pre>{@code
569   * Multimap<K, V> multimap = Multimaps.synchronizedMultimap(
570   *     HashMultimap.<K, V>create());
571   * ...
572   * Collection<V> values = multimap.get(key);  // Needn't be in synchronized block
573   * ...
574   * synchronized (multimap) {  // Synchronizing on multimap, not values!
575   *   Iterator<V> i = values.iterator(); // Must be in synchronized block
576   *   while (i.hasNext()) {
577   *     foo(i.next());
578   *   }
579   * }
580   * }</pre>
581   *
582   * <p>Failure to follow this advice may result in non-deterministic behavior.
583   *
584   * <p>Note that the generated multimap's {@link Multimap#removeAll} and {@link
585   * Multimap#replaceValues} methods return collections that aren't synchronized.
586   *
587   * <p>The returned multimap will be serializable if the specified multimap is serializable.
588   *
589   * @param multimap the multimap to be wrapped in a synchronized view
590   * @return a synchronized view of the specified multimap
591   */
592  public static <K, V> Multimap<K, V> synchronizedMultimap(Multimap<K, V> multimap) {
593    return Synchronized.multimap(multimap, null);
594  }
595
596  /**
597   * Returns an unmodifiable view of the specified multimap. Query operations on the returned
598   * multimap "read through" to the specified multimap, and attempts to modify the returned
599   * multimap, either directly or through the multimap's views, result in an {@code
600   * UnsupportedOperationException}.
601   *
602   * <p>The returned multimap will be serializable if the specified multimap is serializable.
603   *
604   * @param delegate the multimap for which an unmodifiable view is to be returned
605   * @return an unmodifiable view of the specified multimap
606   */
607  public static <K, V> Multimap<K, V> unmodifiableMultimap(Multimap<K, V> delegate) {
608    if (delegate instanceof UnmodifiableMultimap || delegate instanceof ImmutableMultimap) {
609      return delegate;
610    }
611    return new UnmodifiableMultimap<>(delegate);
612  }
613
614  /**
615   * Simply returns its argument.
616   *
617   * @deprecated no need to use this
618   * @since 10.0
619   */
620  @Deprecated
621  public static <K, V> Multimap<K, V> unmodifiableMultimap(ImmutableMultimap<K, V> delegate) {
622    return checkNotNull(delegate);
623  }
624
625  private static class UnmodifiableMultimap<K, V> extends ForwardingMultimap<K, V>
626      implements Serializable {
627    final Multimap<K, V> delegate;
628    @LazyInit transient @Nullable Collection<Entry<K, V>> entries;
629    @LazyInit transient @Nullable Multiset<K> keys;
630    @LazyInit transient @Nullable Set<K> keySet;
631    @LazyInit transient @Nullable Collection<V> values;
632    @LazyInit transient @Nullable Map<K, Collection<V>> map;
633
634    UnmodifiableMultimap(final Multimap<K, V> delegate) {
635      this.delegate = checkNotNull(delegate);
636    }
637
638    @Override
639    protected Multimap<K, V> delegate() {
640      return delegate;
641    }
642
643    @Override
644    public void clear() {
645      throw new UnsupportedOperationException();
646    }
647
648    @Override
649    public Map<K, Collection<V>> asMap() {
650      Map<K, Collection<V>> result = map;
651      if (result == null) {
652        result =
653            map =
654                Collections.unmodifiableMap(
655                    Maps.transformValues(
656                        delegate.asMap(),
657                        new Function<Collection<V>, Collection<V>>() {
658                          @Override
659                          public Collection<V> apply(Collection<V> collection) {
660                            return unmodifiableValueCollection(collection);
661                          }
662                        }));
663      }
664      return result;
665    }
666
667    @Override
668    public Collection<Entry<K, V>> entries() {
669      Collection<Entry<K, V>> result = entries;
670      if (result == null) {
671        entries = result = unmodifiableEntries(delegate.entries());
672      }
673      return result;
674    }
675
676    @Override
677    public void forEach(BiConsumer<? super K, ? super V> consumer) {
678      delegate.forEach(checkNotNull(consumer));
679    }
680
681    @Override
682    public Collection<V> get(K key) {
683      return unmodifiableValueCollection(delegate.get(key));
684    }
685
686    @Override
687    public Multiset<K> keys() {
688      Multiset<K> result = keys;
689      if (result == null) {
690        keys = result = Multisets.unmodifiableMultiset(delegate.keys());
691      }
692      return result;
693    }
694
695    @Override
696    public Set<K> keySet() {
697      Set<K> result = keySet;
698      if (result == null) {
699        keySet = result = Collections.unmodifiableSet(delegate.keySet());
700      }
701      return result;
702    }
703
704    @Override
705    public boolean put(K key, V value) {
706      throw new UnsupportedOperationException();
707    }
708
709    @Override
710    public boolean putAll(K key, Iterable<? extends V> values) {
711      throw new UnsupportedOperationException();
712    }
713
714    @Override
715    public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
716      throw new UnsupportedOperationException();
717    }
718
719    @Override
720    public boolean remove(Object key, Object value) {
721      throw new UnsupportedOperationException();
722    }
723
724    @Override
725    public Collection<V> removeAll(Object key) {
726      throw new UnsupportedOperationException();
727    }
728
729    @Override
730    public Collection<V> replaceValues(K key, Iterable<? extends V> values) {
731      throw new UnsupportedOperationException();
732    }
733
734    @Override
735    public Collection<V> values() {
736      Collection<V> result = values;
737      if (result == null) {
738        values = result = Collections.unmodifiableCollection(delegate.values());
739      }
740      return result;
741    }
742
743    private static final long serialVersionUID = 0;
744  }
745
746  private static class UnmodifiableListMultimap<K, V> extends UnmodifiableMultimap<K, V>
747      implements ListMultimap<K, V> {
748    UnmodifiableListMultimap(ListMultimap<K, V> delegate) {
749      super(delegate);
750    }
751
752    @Override
753    public ListMultimap<K, V> delegate() {
754      return (ListMultimap<K, V>) super.delegate();
755    }
756
757    @Override
758    public List<V> get(K key) {
759      return Collections.unmodifiableList(delegate().get(key));
760    }
761
762    @Override
763    public List<V> removeAll(Object key) {
764      throw new UnsupportedOperationException();
765    }
766
767    @Override
768    public List<V> replaceValues(K key, Iterable<? extends V> values) {
769      throw new UnsupportedOperationException();
770    }
771
772    private static final long serialVersionUID = 0;
773  }
774
775  private static class UnmodifiableSetMultimap<K, V> extends UnmodifiableMultimap<K, V>
776      implements SetMultimap<K, V> {
777    UnmodifiableSetMultimap(SetMultimap<K, V> delegate) {
778      super(delegate);
779    }
780
781    @Override
782    public SetMultimap<K, V> delegate() {
783      return (SetMultimap<K, V>) super.delegate();
784    }
785
786    @Override
787    public Set<V> get(K key) {
788      /*
789       * Note that this doesn't return a SortedSet when delegate is a
790       * SortedSetMultiset, unlike (SortedSet<V>) super.get().
791       */
792      return Collections.unmodifiableSet(delegate().get(key));
793    }
794
795    @Override
796    public Set<Map.Entry<K, V>> entries() {
797      return Maps.unmodifiableEntrySet(delegate().entries());
798    }
799
800    @Override
801    public Set<V> removeAll(Object key) {
802      throw new UnsupportedOperationException();
803    }
804
805    @Override
806    public Set<V> replaceValues(K key, Iterable<? extends V> values) {
807      throw new UnsupportedOperationException();
808    }
809
810    private static final long serialVersionUID = 0;
811  }
812
813  private static class UnmodifiableSortedSetMultimap<K, V> extends UnmodifiableSetMultimap<K, V>
814      implements SortedSetMultimap<K, V> {
815    UnmodifiableSortedSetMultimap(SortedSetMultimap<K, V> delegate) {
816      super(delegate);
817    }
818
819    @Override
820    public SortedSetMultimap<K, V> delegate() {
821      return (SortedSetMultimap<K, V>) super.delegate();
822    }
823
824    @Override
825    public SortedSet<V> get(K key) {
826      return Collections.unmodifiableSortedSet(delegate().get(key));
827    }
828
829    @Override
830    public SortedSet<V> removeAll(Object key) {
831      throw new UnsupportedOperationException();
832    }
833
834    @Override
835    public SortedSet<V> replaceValues(K key, Iterable<? extends V> values) {
836      throw new UnsupportedOperationException();
837    }
838
839    @Override
840    public Comparator<? super V> valueComparator() {
841      return delegate().valueComparator();
842    }
843
844    private static final long serialVersionUID = 0;
845  }
846
847  /**
848   * Returns a synchronized (thread-safe) {@code SetMultimap} backed by the specified multimap.
849   *
850   * <p>You must follow the warnings described in {@link #synchronizedMultimap}.
851   *
852   * <p>The returned multimap will be serializable if the specified multimap is serializable.
853   *
854   * @param multimap the multimap to be wrapped
855   * @return a synchronized view of the specified multimap
856   */
857  public static <K, V> SetMultimap<K, V> synchronizedSetMultimap(SetMultimap<K, V> multimap) {
858    return Synchronized.setMultimap(multimap, null);
859  }
860
861  /**
862   * Returns an unmodifiable view of the specified {@code SetMultimap}. Query operations on the
863   * returned multimap "read through" to the specified multimap, and attempts to modify the returned
864   * multimap, either directly or through the multimap's views, result in an {@code
865   * UnsupportedOperationException}.
866   *
867   * <p>The returned multimap will be serializable if the specified multimap is serializable.
868   *
869   * @param delegate the multimap for which an unmodifiable view is to be returned
870   * @return an unmodifiable view of the specified multimap
871   */
872  public static <K, V> SetMultimap<K, V> unmodifiableSetMultimap(SetMultimap<K, V> delegate) {
873    if (delegate instanceof UnmodifiableSetMultimap || delegate instanceof ImmutableSetMultimap) {
874      return delegate;
875    }
876    return new UnmodifiableSetMultimap<>(delegate);
877  }
878
879  /**
880   * Simply returns its argument.
881   *
882   * @deprecated no need to use this
883   * @since 10.0
884   */
885  @Deprecated
886  public static <K, V> SetMultimap<K, V> unmodifiableSetMultimap(
887      ImmutableSetMultimap<K, V> delegate) {
888    return checkNotNull(delegate);
889  }
890
891  /**
892   * Returns a synchronized (thread-safe) {@code SortedSetMultimap} backed by the specified
893   * multimap.
894   *
895   * <p>You must follow the warnings described in {@link #synchronizedMultimap}.
896   *
897   * <p>The returned multimap will be serializable if the specified multimap is serializable.
898   *
899   * @param multimap the multimap to be wrapped
900   * @return a synchronized view of the specified multimap
901   */
902  public static <K, V> SortedSetMultimap<K, V> synchronizedSortedSetMultimap(
903      SortedSetMultimap<K, V> multimap) {
904    return Synchronized.sortedSetMultimap(multimap, null);
905  }
906
907  /**
908   * Returns an unmodifiable view of the specified {@code SortedSetMultimap}. Query operations on
909   * the returned multimap "read through" to the specified multimap, and attempts to modify the
910   * returned multimap, either directly or through the multimap's views, result in an {@code
911   * UnsupportedOperationException}.
912   *
913   * <p>The returned multimap will be serializable if the specified multimap is serializable.
914   *
915   * @param delegate the multimap for which an unmodifiable view is to be returned
916   * @return an unmodifiable view of the specified multimap
917   */
918  public static <K, V> SortedSetMultimap<K, V> unmodifiableSortedSetMultimap(
919      SortedSetMultimap<K, V> delegate) {
920    if (delegate instanceof UnmodifiableSortedSetMultimap) {
921      return delegate;
922    }
923    return new UnmodifiableSortedSetMultimap<>(delegate);
924  }
925
926  /**
927   * Returns a synchronized (thread-safe) {@code ListMultimap} backed by the specified multimap.
928   *
929   * <p>You must follow the warnings described in {@link #synchronizedMultimap}.
930   *
931   * @param multimap the multimap to be wrapped
932   * @return a synchronized view of the specified multimap
933   */
934  public static <K, V> ListMultimap<K, V> synchronizedListMultimap(ListMultimap<K, V> multimap) {
935    return Synchronized.listMultimap(multimap, null);
936  }
937
938  /**
939   * Returns an unmodifiable view of the specified {@code ListMultimap}. Query operations on the
940   * returned multimap "read through" to the specified multimap, and attempts to modify the returned
941   * multimap, either directly or through the multimap's views, result in an {@code
942   * UnsupportedOperationException}.
943   *
944   * <p>The returned multimap will be serializable if the specified multimap is serializable.
945   *
946   * @param delegate the multimap for which an unmodifiable view is to be returned
947   * @return an unmodifiable view of the specified multimap
948   */
949  public static <K, V> ListMultimap<K, V> unmodifiableListMultimap(ListMultimap<K, V> delegate) {
950    if (delegate instanceof UnmodifiableListMultimap || delegate instanceof ImmutableListMultimap) {
951      return delegate;
952    }
953    return new UnmodifiableListMultimap<>(delegate);
954  }
955
956  /**
957   * Simply returns its argument.
958   *
959   * @deprecated no need to use this
960   * @since 10.0
961   */
962  @Deprecated
963  public static <K, V> ListMultimap<K, V> unmodifiableListMultimap(
964      ImmutableListMultimap<K, V> delegate) {
965    return checkNotNull(delegate);
966  }
967
968  /**
969   * Returns an unmodifiable view of the specified collection, preserving the interface for
970   * instances of {@code SortedSet}, {@code Set}, {@code List} and {@code Collection}, in that order
971   * of preference.
972   *
973   * @param collection the collection for which to return an unmodifiable view
974   * @return an unmodifiable view of the collection
975   */
976  private static <V> Collection<V> unmodifiableValueCollection(Collection<V> collection) {
977    if (collection instanceof SortedSet) {
978      return Collections.unmodifiableSortedSet((SortedSet<V>) collection);
979    } else if (collection instanceof Set) {
980      return Collections.unmodifiableSet((Set<V>) collection);
981    } else if (collection instanceof List) {
982      return Collections.unmodifiableList((List<V>) collection);
983    }
984    return Collections.unmodifiableCollection(collection);
985  }
986
987  /**
988   * Returns an unmodifiable view of the specified collection of entries. The {@link Entry#setValue}
989   * operation throws an {@link UnsupportedOperationException}. If the specified collection is a
990   * {@code Set}, the returned collection is also a {@code Set}.
991   *
992   * @param entries the entries for which to return an unmodifiable view
993   * @return an unmodifiable view of the entries
994   */
995  private static <K, V> Collection<Entry<K, V>> unmodifiableEntries(
996      Collection<Entry<K, V>> entries) {
997    if (entries instanceof Set) {
998      return Maps.unmodifiableEntrySet((Set<Entry<K, V>>) entries);
999    }
1000    return new Maps.UnmodifiableEntries<>(Collections.unmodifiableCollection(entries));
1001  }
1002
1003  /**
1004   * Returns {@link ListMultimap#asMap multimap.asMap()}, with its type corrected from {@code Map<K,
1005   * Collection<V>>} to {@code Map<K, List<V>>}.
1006   *
1007   * @since 15.0
1008   */
1009  @Beta
1010  @SuppressWarnings("unchecked")
1011  // safe by specification of ListMultimap.asMap()
1012  public static <K, V> Map<K, List<V>> asMap(ListMultimap<K, V> multimap) {
1013    return (Map<K, List<V>>) (Map<K, ?>) multimap.asMap();
1014  }
1015
1016  /**
1017   * Returns {@link SetMultimap#asMap multimap.asMap()}, with its type corrected from {@code Map<K,
1018   * Collection<V>>} to {@code Map<K, Set<V>>}.
1019   *
1020   * @since 15.0
1021   */
1022  @Beta
1023  @SuppressWarnings("unchecked")
1024  // safe by specification of SetMultimap.asMap()
1025  public static <K, V> Map<K, Set<V>> asMap(SetMultimap<K, V> multimap) {
1026    return (Map<K, Set<V>>) (Map<K, ?>) multimap.asMap();
1027  }
1028
1029  /**
1030   * Returns {@link SortedSetMultimap#asMap multimap.asMap()}, with its type corrected from {@code
1031   * Map<K, Collection<V>>} to {@code Map<K, SortedSet<V>>}.
1032   *
1033   * @since 15.0
1034   */
1035  @Beta
1036  @SuppressWarnings("unchecked")
1037  // safe by specification of SortedSetMultimap.asMap()
1038  public static <K, V> Map<K, SortedSet<V>> asMap(SortedSetMultimap<K, V> multimap) {
1039    return (Map<K, SortedSet<V>>) (Map<K, ?>) multimap.asMap();
1040  }
1041
1042  /**
1043   * Returns {@link Multimap#asMap multimap.asMap()}. This is provided for parity with the other
1044   * more strongly-typed {@code asMap()} implementations.
1045   *
1046   * @since 15.0
1047   */
1048  @Beta
1049  public static <K, V> Map<K, Collection<V>> asMap(Multimap<K, V> multimap) {
1050    return multimap.asMap();
1051  }
1052
1053  /**
1054   * Returns a multimap view of the specified map. The multimap is backed by the map, so changes to
1055   * the map are reflected in the multimap, and vice versa. If the map is modified while an
1056   * iteration over one of the multimap's collection views is in progress (except through the
1057   * iterator's own {@code remove} operation, or through the {@code setValue} operation on a map
1058   * entry returned by the iterator), the results of the iteration are undefined.
1059   *
1060   * <p>The multimap supports mapping removal, which removes the corresponding mapping from the map.
1061   * It does not support any operations which might add mappings, such as {@code put}, {@code
1062   * putAll} or {@code replaceValues}.
1063   *
1064   * <p>The returned multimap will be serializable if the specified map is serializable.
1065   *
1066   * @param map the backing map for the returned multimap view
1067   */
1068  public static <K, V> SetMultimap<K, V> forMap(Map<K, V> map) {
1069    return new MapMultimap<>(map);
1070  }
1071
1072  /** @see Multimaps#forMap */
1073  private static class MapMultimap<K, V> extends AbstractMultimap<K, V>
1074      implements SetMultimap<K, V>, Serializable {
1075    final Map<K, V> map;
1076
1077    MapMultimap(Map<K, V> map) {
1078      this.map = checkNotNull(map);
1079    }
1080
1081    @Override
1082    public int size() {
1083      return map.size();
1084    }
1085
1086    @Override
1087    public boolean containsKey(Object key) {
1088      return map.containsKey(key);
1089    }
1090
1091    @Override
1092    public boolean containsValue(Object value) {
1093      return map.containsValue(value);
1094    }
1095
1096    @Override
1097    public boolean containsEntry(Object key, Object value) {
1098      return map.entrySet().contains(Maps.immutableEntry(key, value));
1099    }
1100
1101    @Override
1102    public Set<V> get(final K key) {
1103      return new Sets.ImprovedAbstractSet<V>() {
1104        @Override
1105        public Iterator<V> iterator() {
1106          return new Iterator<V>() {
1107            int i;
1108
1109            @Override
1110            public boolean hasNext() {
1111              return (i == 0) && map.containsKey(key);
1112            }
1113
1114            @Override
1115            public V next() {
1116              if (!hasNext()) {
1117                throw new NoSuchElementException();
1118              }
1119              i++;
1120              return map.get(key);
1121            }
1122
1123            @Override
1124            public void remove() {
1125              checkRemove(i == 1);
1126              i = -1;
1127              map.remove(key);
1128            }
1129          };
1130        }
1131
1132        @Override
1133        public int size() {
1134          return map.containsKey(key) ? 1 : 0;
1135        }
1136      };
1137    }
1138
1139    @Override
1140    public boolean put(K key, V value) {
1141      throw new UnsupportedOperationException();
1142    }
1143
1144    @Override
1145    public boolean putAll(K key, Iterable<? extends V> values) {
1146      throw new UnsupportedOperationException();
1147    }
1148
1149    @Override
1150    public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
1151      throw new UnsupportedOperationException();
1152    }
1153
1154    @Override
1155    public Set<V> replaceValues(K key, Iterable<? extends V> values) {
1156      throw new UnsupportedOperationException();
1157    }
1158
1159    @Override
1160    public boolean remove(Object key, Object value) {
1161      return map.entrySet().remove(Maps.immutableEntry(key, value));
1162    }
1163
1164    @Override
1165    public Set<V> removeAll(Object key) {
1166      Set<V> values = new HashSet<V>(2);
1167      if (!map.containsKey(key)) {
1168        return values;
1169      }
1170      values.add(map.remove(key));
1171      return values;
1172    }
1173
1174    @Override
1175    public void clear() {
1176      map.clear();
1177    }
1178
1179    @Override
1180    Set<K> createKeySet() {
1181      return map.keySet();
1182    }
1183
1184    @Override
1185    Collection<V> createValues() {
1186      return map.values();
1187    }
1188
1189    @Override
1190    public Set<Entry<K, V>> entries() {
1191      return map.entrySet();
1192    }
1193
1194    @Override
1195    Collection<Entry<K, V>> createEntries() {
1196      throw new AssertionError("unreachable");
1197    }
1198
1199    @Override
1200    Multiset<K> createKeys() {
1201      return new Multimaps.Keys<K, V>(this);
1202    }
1203
1204    @Override
1205    Iterator<Entry<K, V>> entryIterator() {
1206      return map.entrySet().iterator();
1207    }
1208
1209    @Override
1210    Map<K, Collection<V>> createAsMap() {
1211      return new AsMap<>(this);
1212    }
1213
1214    @Override
1215    public int hashCode() {
1216      return map.hashCode();
1217    }
1218
1219    private static final long serialVersionUID = 7845222491160860175L;
1220  }
1221
1222  /**
1223   * Returns a view of a multimap where each value is transformed by a function. All other
1224   * properties of the multimap, such as iteration order, are left intact. For example, the code:
1225   *
1226   * <pre>{@code
1227   * Multimap<String, Integer> multimap =
1228   *     ImmutableSetMultimap.of("a", 2, "b", -3, "b", -3, "a", 4, "c", 6);
1229   * Function<Integer, String> square = new Function<Integer, String>() {
1230   *     public String apply(Integer in) {
1231   *       return Integer.toString(in * in);
1232   *     }
1233   * };
1234   * Multimap<String, String> transformed =
1235   *     Multimaps.transformValues(multimap, square);
1236   *   System.out.println(transformed);
1237   * }</pre>
1238   *
1239   * ... prints {@code {a=[4, 16], b=[9, 9], c=[36]}}.
1240   *
1241   * <p>Changes in the underlying multimap are reflected in this view. Conversely, this view
1242   * supports removal operations, and these are reflected in the underlying multimap.
1243   *
1244   * <p>It's acceptable for the underlying multimap to contain null keys, and even null values
1245   * provided that the function is capable of accepting null input. The transformed multimap might
1246   * contain null values, if the function sometimes gives a null result.
1247   *
1248   * <p>The returned multimap is not thread-safe or serializable, even if the underlying multimap
1249   * is. The {@code equals} and {@code hashCode} methods of the returned multimap are meaningless,
1250   * since there is not a definition of {@code equals} or {@code hashCode} for general collections,
1251   * and {@code get()} will return a general {@code Collection} as opposed to a {@code List} or a
1252   * {@code Set}.
1253   *
1254   * <p>The function is applied lazily, invoked when needed. This is necessary for the returned
1255   * multimap to be a view, but it means that the function will be applied many times for bulk
1256   * operations like {@link Multimap#containsValue} and {@code Multimap.toString()}. For this to
1257   * perform well, {@code function} should be fast. To avoid lazy evaluation when the returned
1258   * multimap doesn't need to be a view, copy the returned multimap into a new multimap of your
1259   * choosing.
1260   *
1261   * @since 7.0
1262   */
1263  public static <K, V1, V2> Multimap<K, V2> transformValues(
1264      Multimap<K, V1> fromMultimap, final Function<? super V1, V2> function) {
1265    checkNotNull(function);
1266    EntryTransformer<K, V1, V2> transformer = Maps.asEntryTransformer(function);
1267    return transformEntries(fromMultimap, transformer);
1268  }
1269
1270  /**
1271   * Returns a view of a {@code ListMultimap} where each value is transformed by a function. All
1272   * other properties of the multimap, such as iteration order, are left intact. For example, the
1273   * code:
1274   *
1275   * <pre>{@code
1276   * ListMultimap<String, Integer> multimap
1277   *      = ImmutableListMultimap.of("a", 4, "a", 16, "b", 9);
1278   * Function<Integer, Double> sqrt =
1279   *     new Function<Integer, Double>() {
1280   *       public Double apply(Integer in) {
1281   *         return Math.sqrt((int) in);
1282   *       }
1283   *     };
1284   * ListMultimap<String, Double> transformed = Multimaps.transformValues(map,
1285   *     sqrt);
1286   * System.out.println(transformed);
1287   * }</pre>
1288   *
1289   * ... prints {@code {a=[2.0, 4.0], b=[3.0]}}.
1290   *
1291   * <p>Changes in the underlying multimap are reflected in this view. Conversely, this view
1292   * supports removal operations, and these are reflected in the underlying multimap.
1293   *
1294   * <p>It's acceptable for the underlying multimap to contain null keys, and even null values
1295   * provided that the function is capable of accepting null input. The transformed multimap might
1296   * contain null values, if the function sometimes gives a null result.
1297   *
1298   * <p>The returned multimap is not thread-safe or serializable, even if the underlying multimap
1299   * is.
1300   *
1301   * <p>The function is applied lazily, invoked when needed. This is necessary for the returned
1302   * multimap to be a view, but it means that the function will be applied many times for bulk
1303   * operations like {@link Multimap#containsValue} and {@code Multimap.toString()}. For this to
1304   * perform well, {@code function} should be fast. To avoid lazy evaluation when the returned
1305   * multimap doesn't need to be a view, copy the returned multimap into a new multimap of your
1306   * choosing.
1307   *
1308   * @since 7.0
1309   */
1310  public static <K, V1, V2> ListMultimap<K, V2> transformValues(
1311      ListMultimap<K, V1> fromMultimap, final Function<? super V1, V2> function) {
1312    checkNotNull(function);
1313    EntryTransformer<K, V1, V2> transformer = Maps.asEntryTransformer(function);
1314    return transformEntries(fromMultimap, transformer);
1315  }
1316
1317  /**
1318   * Returns a view of a multimap whose values are derived from the original multimap's entries. In
1319   * contrast to {@link #transformValues}, this method's entry-transformation logic may depend on
1320   * the key as well as the value.
1321   *
1322   * <p>All other properties of the transformed multimap, such as iteration order, are left intact.
1323   * For example, the code:
1324   *
1325   * <pre>{@code
1326   * SetMultimap<String, Integer> multimap =
1327   *     ImmutableSetMultimap.of("a", 1, "a", 4, "b", -6);
1328   * EntryTransformer<String, Integer, String> transformer =
1329   *     new EntryTransformer<String, Integer, String>() {
1330   *       public String transformEntry(String key, Integer value) {
1331   *          return (value >= 0) ? key : "no" + key;
1332   *       }
1333   *     };
1334   * Multimap<String, String> transformed =
1335   *     Multimaps.transformEntries(multimap, transformer);
1336   * System.out.println(transformed);
1337   * }</pre>
1338   *
1339   * ... prints {@code {a=[a, a], b=[nob]}}.
1340   *
1341   * <p>Changes in the underlying multimap are reflected in this view. Conversely, this view
1342   * supports removal operations, and these are reflected in the underlying multimap.
1343   *
1344   * <p>It's acceptable for the underlying multimap to contain null keys and null values provided
1345   * that the transformer is capable of accepting null inputs. The transformed multimap might
1346   * contain null values if the transformer sometimes gives a null result.
1347   *
1348   * <p>The returned multimap is not thread-safe or serializable, even if the underlying multimap
1349   * is. The {@code equals} and {@code hashCode} methods of the returned multimap are meaningless,
1350   * since there is not a definition of {@code equals} or {@code hashCode} for general collections,
1351   * and {@code get()} will return a general {@code Collection} as opposed to a {@code List} or a
1352   * {@code Set}.
1353   *
1354   * <p>The transformer is applied lazily, invoked when needed. This is necessary for the returned
1355   * multimap to be a view, but it means that the transformer will be applied many times for bulk
1356   * operations like {@link Multimap#containsValue} and {@link Object#toString}. For this to perform
1357   * well, {@code transformer} should be fast. To avoid lazy evaluation when the returned multimap
1358   * doesn't need to be a view, copy the returned multimap into a new multimap of your choosing.
1359   *
1360   * <p><b>Warning:</b> This method assumes that for any instance {@code k} of {@code
1361   * EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies that {@code k2} is also of
1362   * type {@code K}. Using an {@code EntryTransformer} key type for which this may not hold, such as
1363   * {@code ArrayList}, may risk a {@code ClassCastException} when calling methods on the
1364   * transformed multimap.
1365   *
1366   * @since 7.0
1367   */
1368  public static <K, V1, V2> Multimap<K, V2> transformEntries(
1369      Multimap<K, V1> fromMap, EntryTransformer<? super K, ? super V1, V2> transformer) {
1370    return new TransformedEntriesMultimap<>(fromMap, transformer);
1371  }
1372
1373  /**
1374   * Returns a view of a {@code ListMultimap} whose values are derived from the original multimap's
1375   * entries. In contrast to {@link #transformValues(ListMultimap, Function)}, this method's
1376   * entry-transformation logic may depend on the key as well as the value.
1377   *
1378   * <p>All other properties of the transformed multimap, such as iteration order, are left intact.
1379   * For example, the code:
1380   *
1381   * <pre>{@code
1382   * Multimap<String, Integer> multimap =
1383   *     ImmutableMultimap.of("a", 1, "a", 4, "b", 6);
1384   * EntryTransformer<String, Integer, String> transformer =
1385   *     new EntryTransformer<String, Integer, String>() {
1386   *       public String transformEntry(String key, Integer value) {
1387   *         return key + value;
1388   *       }
1389   *     };
1390   * Multimap<String, String> transformed =
1391   *     Multimaps.transformEntries(multimap, transformer);
1392   * System.out.println(transformed);
1393   * }</pre>
1394   *
1395   * ... prints {@code {"a"=["a1", "a4"], "b"=["b6"]}}.
1396   *
1397   * <p>Changes in the underlying multimap are reflected in this view. Conversely, this view
1398   * supports removal operations, and these are reflected in the underlying multimap.
1399   *
1400   * <p>It's acceptable for the underlying multimap to contain null keys and null values provided
1401   * that the transformer is capable of accepting null inputs. The transformed multimap might
1402   * contain null values if the transformer sometimes gives a null result.
1403   *
1404   * <p>The returned multimap is not thread-safe or serializable, even if the underlying multimap
1405   * is.
1406   *
1407   * <p>The transformer is applied lazily, invoked when needed. This is necessary for the returned
1408   * multimap to be a view, but it means that the transformer will be applied many times for bulk
1409   * operations like {@link Multimap#containsValue} and {@link Object#toString}. For this to perform
1410   * well, {@code transformer} should be fast. To avoid lazy evaluation when the returned multimap
1411   * doesn't need to be a view, copy the returned multimap into a new multimap of your choosing.
1412   *
1413   * <p><b>Warning:</b> This method assumes that for any instance {@code k} of {@code
1414   * EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies that {@code k2} is also of
1415   * type {@code K}. Using an {@code EntryTransformer} key type for which this may not hold, such as
1416   * {@code ArrayList}, may risk a {@code ClassCastException} when calling methods on the
1417   * transformed multimap.
1418   *
1419   * @since 7.0
1420   */
1421  public static <K, V1, V2> ListMultimap<K, V2> transformEntries(
1422      ListMultimap<K, V1> fromMap, EntryTransformer<? super K, ? super V1, V2> transformer) {
1423    return new TransformedEntriesListMultimap<>(fromMap, transformer);
1424  }
1425
1426  private static class TransformedEntriesMultimap<K, V1, V2> extends AbstractMultimap<K, V2> {
1427    final Multimap<K, V1> fromMultimap;
1428    final EntryTransformer<? super K, ? super V1, V2> transformer;
1429
1430    TransformedEntriesMultimap(
1431        Multimap<K, V1> fromMultimap,
1432        final EntryTransformer<? super K, ? super V1, V2> transformer) {
1433      this.fromMultimap = checkNotNull(fromMultimap);
1434      this.transformer = checkNotNull(transformer);
1435    }
1436
1437    Collection<V2> transform(K key, Collection<V1> values) {
1438      Function<? super V1, V2> function = Maps.asValueToValueFunction(transformer, key);
1439      if (values instanceof List) {
1440        return Lists.transform((List<V1>) values, function);
1441      } else {
1442        return Collections2.transform(values, function);
1443      }
1444    }
1445
1446    @Override
1447    Map<K, Collection<V2>> createAsMap() {
1448      return Maps.transformEntries(
1449          fromMultimap.asMap(),
1450          new EntryTransformer<K, Collection<V1>, Collection<V2>>() {
1451            @Override
1452            public Collection<V2> transformEntry(K key, Collection<V1> value) {
1453              return transform(key, value);
1454            }
1455          });
1456    }
1457
1458    @Override
1459    public void clear() {
1460      fromMultimap.clear();
1461    }
1462
1463    @Override
1464    public boolean containsKey(Object key) {
1465      return fromMultimap.containsKey(key);
1466    }
1467
1468    @Override
1469    Collection<Entry<K, V2>> createEntries() {
1470      return new Entries();
1471    }
1472
1473    @Override
1474    Iterator<Entry<K, V2>> entryIterator() {
1475      return Iterators.transform(
1476          fromMultimap.entries().iterator(), Maps.<K, V1, V2>asEntryToEntryFunction(transformer));
1477    }
1478
1479    @Override
1480    public Collection<V2> get(final K key) {
1481      return transform(key, fromMultimap.get(key));
1482    }
1483
1484    @Override
1485    public boolean isEmpty() {
1486      return fromMultimap.isEmpty();
1487    }
1488
1489    @Override
1490    Set<K> createKeySet() {
1491      return fromMultimap.keySet();
1492    }
1493
1494    @Override
1495    Multiset<K> createKeys() {
1496      return fromMultimap.keys();
1497    }
1498
1499    @Override
1500    public boolean put(K key, V2 value) {
1501      throw new UnsupportedOperationException();
1502    }
1503
1504    @Override
1505    public boolean putAll(K key, Iterable<? extends V2> values) {
1506      throw new UnsupportedOperationException();
1507    }
1508
1509    @Override
1510    public boolean putAll(Multimap<? extends K, ? extends V2> multimap) {
1511      throw new UnsupportedOperationException();
1512    }
1513
1514    @SuppressWarnings("unchecked")
1515    @Override
1516    public boolean remove(Object key, Object value) {
1517      return get((K) key).remove(value);
1518    }
1519
1520    @SuppressWarnings("unchecked")
1521    @Override
1522    public Collection<V2> removeAll(Object key) {
1523      return transform((K) key, fromMultimap.removeAll(key));
1524    }
1525
1526    @Override
1527    public Collection<V2> replaceValues(K key, Iterable<? extends V2> values) {
1528      throw new UnsupportedOperationException();
1529    }
1530
1531    @Override
1532    public int size() {
1533      return fromMultimap.size();
1534    }
1535
1536    @Override
1537    Collection<V2> createValues() {
1538      return Collections2.transform(
1539          fromMultimap.entries(), Maps.<K, V1, V2>asEntryToValueFunction(transformer));
1540    }
1541  }
1542
1543  private static final class TransformedEntriesListMultimap<K, V1, V2>
1544      extends TransformedEntriesMultimap<K, V1, V2> implements ListMultimap<K, V2> {
1545
1546    TransformedEntriesListMultimap(
1547        ListMultimap<K, V1> fromMultimap, EntryTransformer<? super K, ? super V1, V2> transformer) {
1548      super(fromMultimap, transformer);
1549    }
1550
1551    @Override
1552    List<V2> transform(K key, Collection<V1> values) {
1553      return Lists.transform((List<V1>) values, Maps.asValueToValueFunction(transformer, key));
1554    }
1555
1556    @Override
1557    public List<V2> get(K key) {
1558      return transform(key, fromMultimap.get(key));
1559    }
1560
1561    @SuppressWarnings("unchecked")
1562    @Override
1563    public List<V2> removeAll(Object key) {
1564      return transform((K) key, fromMultimap.removeAll(key));
1565    }
1566
1567    @Override
1568    public List<V2> replaceValues(K key, Iterable<? extends V2> values) {
1569      throw new UnsupportedOperationException();
1570    }
1571  }
1572
1573  /**
1574   * Creates an index {@code ImmutableListMultimap} that contains the results of applying a
1575   * specified function to each item in an {@code Iterable} of values. Each value will be stored as
1576   * a value in the resulting multimap, yielding a multimap with the same size as the input
1577   * iterable. The key used to store that value in the multimap will be the result of calling the
1578   * function on that value. The resulting multimap is created as an immutable snapshot. In the
1579   * returned multimap, keys appear in the order they are first encountered, and the values
1580   * corresponding to each key appear in the same order as they are encountered.
1581   *
1582   * <p>For example,
1583   *
1584   * <pre>{@code
1585   * List<String> badGuys =
1586   *     Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde");
1587   * Function<String, Integer> stringLengthFunction = ...;
1588   * Multimap<Integer, String> index =
1589   *     Multimaps.index(badGuys, stringLengthFunction);
1590   * System.out.println(index);
1591   * }</pre>
1592   *
1593   * <p>prints
1594   *
1595   * <pre>{@code
1596   * {4=[Inky], 6=[Blinky], 5=[Pinky, Pinky, Clyde]}
1597   * }</pre>
1598   *
1599   * <p>The returned multimap is serializable if its keys and values are all serializable.
1600   *
1601   * @param values the values to use when constructing the {@code ImmutableListMultimap}
1602   * @param keyFunction the function used to produce the key for each value
1603   * @return {@code ImmutableListMultimap} mapping the result of evaluating the function {@code
1604   *     keyFunction} on each value in the input collection to that value
1605   * @throws NullPointerException if any element of {@code values} is {@code null}, or if {@code
1606   *     keyFunction} produces {@code null} for any key
1607   */
1608  public static <K, V> ImmutableListMultimap<K, V> index(
1609      Iterable<V> values, Function<? super V, K> keyFunction) {
1610    return index(values.iterator(), keyFunction);
1611  }
1612
1613  /**
1614   * Creates an index {@code ImmutableListMultimap} that contains the results of applying a
1615   * specified function to each item in an {@code Iterator} of values. Each value will be stored as
1616   * a value in the resulting multimap, yielding a multimap with the same size as the input
1617   * iterator. The key used to store that value in the multimap will be the result of calling the
1618   * function on that value. The resulting multimap is created as an immutable snapshot. In the
1619   * returned multimap, keys appear in the order they are first encountered, and the values
1620   * corresponding to each key appear in the same order as they are encountered.
1621   *
1622   * <p>For example,
1623   *
1624   * <pre>{@code
1625   * List<String> badGuys =
1626   *     Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde");
1627   * Function<String, Integer> stringLengthFunction = ...;
1628   * Multimap<Integer, String> index =
1629   *     Multimaps.index(badGuys.iterator(), stringLengthFunction);
1630   * System.out.println(index);
1631   * }</pre>
1632   *
1633   * <p>prints
1634   *
1635   * <pre>{@code
1636   * {4=[Inky], 6=[Blinky], 5=[Pinky, Pinky, Clyde]}
1637   * }</pre>
1638   *
1639   * <p>The returned multimap is serializable if its keys and values are all serializable.
1640   *
1641   * @param values the values to use when constructing the {@code ImmutableListMultimap}
1642   * @param keyFunction the function used to produce the key for each value
1643   * @return {@code ImmutableListMultimap} mapping the result of evaluating the function {@code
1644   *     keyFunction} on each value in the input collection to that value
1645   * @throws NullPointerException if any element of {@code values} is {@code null}, or if {@code
1646   *     keyFunction} produces {@code null} for any key
1647   * @since 10.0
1648   */
1649  public static <K, V> ImmutableListMultimap<K, V> index(
1650      Iterator<V> values, Function<? super V, K> keyFunction) {
1651    checkNotNull(keyFunction);
1652    ImmutableListMultimap.Builder<K, V> builder = ImmutableListMultimap.builder();
1653    while (values.hasNext()) {
1654      V value = values.next();
1655      checkNotNull(value, values);
1656      builder.put(keyFunction.apply(value), value);
1657    }
1658    return builder.build();
1659  }
1660
1661  static class Keys<K, V> extends AbstractMultiset<K> {
1662    @Weak final Multimap<K, V> multimap;
1663
1664    Keys(Multimap<K, V> multimap) {
1665      this.multimap = multimap;
1666    }
1667
1668    @Override
1669    Iterator<Multiset.Entry<K>> entryIterator() {
1670      return new TransformedIterator<Map.Entry<K, Collection<V>>, Multiset.Entry<K>>(
1671          multimap.asMap().entrySet().iterator()) {
1672        @Override
1673        Multiset.Entry<K> transform(final Map.Entry<K, Collection<V>> backingEntry) {
1674          return new Multisets.AbstractEntry<K>() {
1675            @Override
1676            public K getElement() {
1677              return backingEntry.getKey();
1678            }
1679
1680            @Override
1681            public int getCount() {
1682              return backingEntry.getValue().size();
1683            }
1684          };
1685        }
1686      };
1687    }
1688
1689    @Override
1690    public Spliterator<K> spliterator() {
1691      return CollectSpliterators.map(multimap.entries().spliterator(), Map.Entry::getKey);
1692    }
1693
1694    @Override
1695    public void forEach(Consumer<? super K> consumer) {
1696      checkNotNull(consumer);
1697      multimap.entries().forEach(entry -> consumer.accept(entry.getKey()));
1698    }
1699
1700    @Override
1701    int distinctElements() {
1702      return multimap.asMap().size();
1703    }
1704
1705    @Override
1706    public int size() {
1707      return multimap.size();
1708    }
1709
1710    @Override
1711    public boolean contains(@Nullable Object element) {
1712      return multimap.containsKey(element);
1713    }
1714
1715    @Override
1716    public Iterator<K> iterator() {
1717      return Maps.keyIterator(multimap.entries().iterator());
1718    }
1719
1720    @Override
1721    public int count(@Nullable Object element) {
1722      Collection<V> values = Maps.safeGet(multimap.asMap(), element);
1723      return (values == null) ? 0 : values.size();
1724    }
1725
1726    @Override
1727    public int remove(@Nullable Object element, int occurrences) {
1728      checkNonnegative(occurrences, "occurrences");
1729      if (occurrences == 0) {
1730        return count(element);
1731      }
1732
1733      Collection<V> values = Maps.safeGet(multimap.asMap(), element);
1734
1735      if (values == null) {
1736        return 0;
1737      }
1738
1739      int oldCount = values.size();
1740      if (occurrences >= oldCount) {
1741        values.clear();
1742      } else {
1743        Iterator<V> iterator = values.iterator();
1744        for (int i = 0; i < occurrences; i++) {
1745          iterator.next();
1746          iterator.remove();
1747        }
1748      }
1749      return oldCount;
1750    }
1751
1752    @Override
1753    public void clear() {
1754      multimap.clear();
1755    }
1756
1757    @Override
1758    public Set<K> elementSet() {
1759      return multimap.keySet();
1760    }
1761
1762    @Override
1763    Iterator<K> elementIterator() {
1764      throw new AssertionError("should never be called");
1765    }
1766  }
1767
1768  /** A skeleton implementation of {@link Multimap#entries()}. */
1769  abstract static class Entries<K, V> extends AbstractCollection<Map.Entry<K, V>> {
1770    abstract Multimap<K, V> multimap();
1771
1772    @Override
1773    public int size() {
1774      return multimap().size();
1775    }
1776
1777    @Override
1778    public boolean contains(@Nullable Object o) {
1779      if (o instanceof Map.Entry) {
1780        Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
1781        return multimap().containsEntry(entry.getKey(), entry.getValue());
1782      }
1783      return false;
1784    }
1785
1786    @Override
1787    public boolean remove(@Nullable Object o) {
1788      if (o instanceof Map.Entry) {
1789        Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
1790        return multimap().remove(entry.getKey(), entry.getValue());
1791      }
1792      return false;
1793    }
1794
1795    @Override
1796    public void clear() {
1797      multimap().clear();
1798    }
1799  }
1800
1801  /** A skeleton implementation of {@link Multimap#asMap()}. */
1802  static final class AsMap<K, V> extends Maps.ViewCachingAbstractMap<K, Collection<V>> {
1803    @Weak private final Multimap<K, V> multimap;
1804
1805    AsMap(Multimap<K, V> multimap) {
1806      this.multimap = checkNotNull(multimap);
1807    }
1808
1809    @Override
1810    public int size() {
1811      return multimap.keySet().size();
1812    }
1813
1814    @Override
1815    protected Set<Entry<K, Collection<V>>> createEntrySet() {
1816      return new EntrySet();
1817    }
1818
1819    void removeValuesForKey(Object key) {
1820      multimap.keySet().remove(key);
1821    }
1822
1823    @WeakOuter
1824    class EntrySet extends Maps.EntrySet<K, Collection<V>> {
1825      @Override
1826      Map<K, Collection<V>> map() {
1827        return AsMap.this;
1828      }
1829
1830      @Override
1831      public Iterator<Entry<K, Collection<V>>> iterator() {
1832        return Maps.asMapEntryIterator(
1833            multimap.keySet(),
1834            new Function<K, Collection<V>>() {
1835              @Override
1836              public Collection<V> apply(K key) {
1837                return multimap.get(key);
1838              }
1839            });
1840      }
1841
1842      @Override
1843      public boolean remove(Object o) {
1844        if (!contains(o)) {
1845          return false;
1846        }
1847        Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
1848        removeValuesForKey(entry.getKey());
1849        return true;
1850      }
1851    }
1852
1853    @SuppressWarnings("unchecked")
1854    @Override
1855    public Collection<V> get(Object key) {
1856      return containsKey(key) ? multimap.get((K) key) : null;
1857    }
1858
1859    @Override
1860    public Collection<V> remove(Object key) {
1861      return containsKey(key) ? multimap.removeAll(key) : null;
1862    }
1863
1864    @Override
1865    public Set<K> keySet() {
1866      return multimap.keySet();
1867    }
1868
1869    @Override
1870    public boolean isEmpty() {
1871      return multimap.isEmpty();
1872    }
1873
1874    @Override
1875    public boolean containsKey(Object key) {
1876      return multimap.containsKey(key);
1877    }
1878
1879    @Override
1880    public void clear() {
1881      multimap.clear();
1882    }
1883  }
1884
1885  /**
1886   * Returns a multimap containing the mappings in {@code unfiltered} whose keys satisfy a
1887   * predicate. The returned multimap is a live view of {@code unfiltered}; changes to one affect
1888   * the other.
1889   *
1890   * <p>The resulting multimap's views have iterators that don't support {@code remove()}, but all
1891   * other methods are supported by the multimap and its views. When adding a key that doesn't
1892   * satisfy the predicate, the multimap's {@code put()}, {@code putAll()}, and {@code
1893   * replaceValues()} methods throw an {@link IllegalArgumentException}.
1894   *
1895   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered
1896   * multimap or its views, only mappings whose keys satisfy the filter will be removed from the
1897   * underlying multimap.
1898   *
1899   * <p>The returned multimap isn't threadsafe or serializable, even if {@code unfiltered} is.
1900   *
1901   * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate across every
1902   * key/value mapping in the underlying multimap and determine which satisfy the filter. When a
1903   * live view is <i>not</i> needed, it may be faster to copy the filtered multimap and use the
1904   * copy.
1905   *
1906   * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>, as documented at
1907   * {@link Predicate#apply}. Do not provide a predicate such as {@code
1908   * Predicates.instanceOf(ArrayList.class)}, which is inconsistent with equals.
1909   *
1910   * @since 11.0
1911   */
1912  public static <K, V> Multimap<K, V> filterKeys(
1913      Multimap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
1914    if (unfiltered instanceof SetMultimap) {
1915      return filterKeys((SetMultimap<K, V>) unfiltered, keyPredicate);
1916    } else if (unfiltered instanceof ListMultimap) {
1917      return filterKeys((ListMultimap<K, V>) unfiltered, keyPredicate);
1918    } else if (unfiltered instanceof FilteredKeyMultimap) {
1919      FilteredKeyMultimap<K, V> prev = (FilteredKeyMultimap<K, V>) unfiltered;
1920      return new FilteredKeyMultimap<>(
1921          prev.unfiltered, Predicates.<K>and(prev.keyPredicate, keyPredicate));
1922    } else if (unfiltered instanceof FilteredMultimap) {
1923      FilteredMultimap<K, V> prev = (FilteredMultimap<K, V>) unfiltered;
1924      return filterFiltered(prev, Maps.<K>keyPredicateOnEntries(keyPredicate));
1925    } else {
1926      return new FilteredKeyMultimap<>(unfiltered, keyPredicate);
1927    }
1928  }
1929
1930  /**
1931   * Returns a multimap containing the mappings in {@code unfiltered} whose keys satisfy a
1932   * predicate. The returned multimap is a live view of {@code unfiltered}; changes to one affect
1933   * the other.
1934   *
1935   * <p>The resulting multimap's views have iterators that don't support {@code remove()}, but all
1936   * other methods are supported by the multimap and its views. When adding a key that doesn't
1937   * satisfy the predicate, the multimap's {@code put()}, {@code putAll()}, and {@code
1938   * replaceValues()} methods throw an {@link IllegalArgumentException}.
1939   *
1940   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered
1941   * multimap or its views, only mappings whose keys satisfy the filter will be removed from the
1942   * underlying multimap.
1943   *
1944   * <p>The returned multimap isn't threadsafe or serializable, even if {@code unfiltered} is.
1945   *
1946   * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate across every
1947   * key/value mapping in the underlying multimap and determine which satisfy the filter. When a
1948   * live view is <i>not</i> needed, it may be faster to copy the filtered multimap and use the
1949   * copy.
1950   *
1951   * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>, as documented at
1952   * {@link Predicate#apply}. Do not provide a predicate such as {@code
1953   * Predicates.instanceOf(ArrayList.class)}, which is inconsistent with equals.
1954   *
1955   * @since 14.0
1956   */
1957  public static <K, V> SetMultimap<K, V> filterKeys(
1958      SetMultimap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
1959    if (unfiltered instanceof FilteredKeySetMultimap) {
1960      FilteredKeySetMultimap<K, V> prev = (FilteredKeySetMultimap<K, V>) unfiltered;
1961      return new FilteredKeySetMultimap<>(
1962          prev.unfiltered(), Predicates.<K>and(prev.keyPredicate, keyPredicate));
1963    } else if (unfiltered instanceof FilteredSetMultimap) {
1964      FilteredSetMultimap<K, V> prev = (FilteredSetMultimap<K, V>) unfiltered;
1965      return filterFiltered(prev, Maps.<K>keyPredicateOnEntries(keyPredicate));
1966    } else {
1967      return new FilteredKeySetMultimap<>(unfiltered, keyPredicate);
1968    }
1969  }
1970
1971  /**
1972   * Returns a multimap containing the mappings in {@code unfiltered} whose keys satisfy a
1973   * predicate. The returned multimap is a live view of {@code unfiltered}; changes to one affect
1974   * the other.
1975   *
1976   * <p>The resulting multimap's views have iterators that don't support {@code remove()}, but all
1977   * other methods are supported by the multimap and its views. When adding a key that doesn't
1978   * satisfy the predicate, the multimap's {@code put()}, {@code putAll()}, and {@code
1979   * replaceValues()} methods throw an {@link IllegalArgumentException}.
1980   *
1981   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered
1982   * multimap or its views, only mappings whose keys satisfy the filter will be removed from the
1983   * underlying multimap.
1984   *
1985   * <p>The returned multimap isn't threadsafe or serializable, even if {@code unfiltered} is.
1986   *
1987   * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate across every
1988   * key/value mapping in the underlying multimap and determine which satisfy the filter. When a
1989   * live view is <i>not</i> needed, it may be faster to copy the filtered multimap and use the
1990   * copy.
1991   *
1992   * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>, as documented at
1993   * {@link Predicate#apply}. Do not provide a predicate such as {@code
1994   * Predicates.instanceOf(ArrayList.class)}, which is inconsistent with equals.
1995   *
1996   * @since 14.0
1997   */
1998  public static <K, V> ListMultimap<K, V> filterKeys(
1999      ListMultimap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
2000    if (unfiltered instanceof FilteredKeyListMultimap) {
2001      FilteredKeyListMultimap<K, V> prev = (FilteredKeyListMultimap<K, V>) unfiltered;
2002      return new FilteredKeyListMultimap<>(
2003          prev.unfiltered(), Predicates.<K>and(prev.keyPredicate, keyPredicate));
2004    } else {
2005      return new FilteredKeyListMultimap<>(unfiltered, keyPredicate);
2006    }
2007  }
2008
2009  /**
2010   * Returns a multimap containing the mappings in {@code unfiltered} whose values satisfy a
2011   * predicate. The returned multimap is a live view of {@code unfiltered}; changes to one affect
2012   * the other.
2013   *
2014   * <p>The resulting multimap's views have iterators that don't support {@code remove()}, but all
2015   * other methods are supported by the multimap and its views. When adding a value that doesn't
2016   * satisfy the predicate, the multimap's {@code put()}, {@code putAll()}, and {@code
2017   * replaceValues()} methods throw an {@link IllegalArgumentException}.
2018   *
2019   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered
2020   * multimap or its views, only mappings whose value satisfy the filter will be removed from the
2021   * underlying multimap.
2022   *
2023   * <p>The returned multimap isn't threadsafe or serializable, even if {@code unfiltered} is.
2024   *
2025   * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate across every
2026   * key/value mapping in the underlying multimap and determine which satisfy the filter. When a
2027   * live view is <i>not</i> needed, it may be faster to copy the filtered multimap and use the
2028   * copy.
2029   *
2030   * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with equals</i>, as documented
2031   * at {@link Predicate#apply}. Do not provide a predicate such as {@code
2032   * Predicates.instanceOf(ArrayList.class)}, which is inconsistent with equals.
2033   *
2034   * @since 11.0
2035   */
2036  public static <K, V> Multimap<K, V> filterValues(
2037      Multimap<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
2038    return filterEntries(unfiltered, Maps.<V>valuePredicateOnEntries(valuePredicate));
2039  }
2040
2041  /**
2042   * Returns a multimap containing the mappings in {@code unfiltered} whose values satisfy a
2043   * predicate. The returned multimap is a live view of {@code unfiltered}; changes to one affect
2044   * the other.
2045   *
2046   * <p>The resulting multimap's views have iterators that don't support {@code remove()}, but all
2047   * other methods are supported by the multimap and its views. When adding a value that doesn't
2048   * satisfy the predicate, the multimap's {@code put()}, {@code putAll()}, and {@code
2049   * replaceValues()} methods throw an {@link IllegalArgumentException}.
2050   *
2051   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered
2052   * multimap or its views, only mappings whose value satisfy the filter will be removed from the
2053   * underlying multimap.
2054   *
2055   * <p>The returned multimap isn't threadsafe or serializable, even if {@code unfiltered} is.
2056   *
2057   * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate across every
2058   * key/value mapping in the underlying multimap and determine which satisfy the filter. When a
2059   * live view is <i>not</i> needed, it may be faster to copy the filtered multimap and use the
2060   * copy.
2061   *
2062   * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with equals</i>, as documented
2063   * at {@link Predicate#apply}. Do not provide a predicate such as {@code
2064   * Predicates.instanceOf(ArrayList.class)}, which is inconsistent with equals.
2065   *
2066   * @since 14.0
2067   */
2068  public static <K, V> SetMultimap<K, V> filterValues(
2069      SetMultimap<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
2070    return filterEntries(unfiltered, Maps.<V>valuePredicateOnEntries(valuePredicate));
2071  }
2072
2073  /**
2074   * Returns a multimap containing the mappings in {@code unfiltered} that satisfy a predicate. The
2075   * returned multimap is a live view of {@code unfiltered}; changes to one affect the other.
2076   *
2077   * <p>The resulting multimap's views have iterators that don't support {@code remove()}, but all
2078   * other methods are supported by the multimap and its views. When adding a key/value pair that
2079   * doesn't satisfy the predicate, multimap's {@code put()}, {@code putAll()}, and {@code
2080   * replaceValues()} methods throw an {@link IllegalArgumentException}.
2081   *
2082   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered
2083   * multimap or its views, only mappings whose keys satisfy the filter will be removed from the
2084   * underlying multimap.
2085   *
2086   * <p>The returned multimap isn't threadsafe or serializable, even if {@code unfiltered} is.
2087   *
2088   * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate across every
2089   * key/value mapping in the underlying multimap and determine which satisfy the filter. When a
2090   * live view is <i>not</i> needed, it may be faster to copy the filtered multimap and use the
2091   * copy.
2092   *
2093   * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with equals</i>, as documented
2094   * at {@link Predicate#apply}.
2095   *
2096   * @since 11.0
2097   */
2098  public static <K, V> Multimap<K, V> filterEntries(
2099      Multimap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
2100    checkNotNull(entryPredicate);
2101    if (unfiltered instanceof SetMultimap) {
2102      return filterEntries((SetMultimap<K, V>) unfiltered, entryPredicate);
2103    }
2104    return (unfiltered instanceof FilteredMultimap)
2105        ? filterFiltered((FilteredMultimap<K, V>) unfiltered, entryPredicate)
2106        : new FilteredEntryMultimap<K, V>(checkNotNull(unfiltered), entryPredicate);
2107  }
2108
2109  /**
2110   * Returns a multimap containing the mappings in {@code unfiltered} that satisfy a predicate. The
2111   * returned multimap is a live view of {@code unfiltered}; changes to one affect the other.
2112   *
2113   * <p>The resulting multimap's views have iterators that don't support {@code remove()}, but all
2114   * other methods are supported by the multimap and its views. When adding a key/value pair that
2115   * doesn't satisfy the predicate, multimap's {@code put()}, {@code putAll()}, and {@code
2116   * replaceValues()} methods throw an {@link IllegalArgumentException}.
2117   *
2118   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered
2119   * multimap or its views, only mappings whose keys satisfy the filter will be removed from the
2120   * underlying multimap.
2121   *
2122   * <p>The returned multimap isn't threadsafe or serializable, even if {@code unfiltered} is.
2123   *
2124   * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate across every
2125   * key/value mapping in the underlying multimap and determine which satisfy the filter. When a
2126   * live view is <i>not</i> needed, it may be faster to copy the filtered multimap and use the
2127   * copy.
2128   *
2129   * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with equals</i>, as documented
2130   * at {@link Predicate#apply}.
2131   *
2132   * @since 14.0
2133   */
2134  public static <K, V> SetMultimap<K, V> filterEntries(
2135      SetMultimap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
2136    checkNotNull(entryPredicate);
2137    return (unfiltered instanceof FilteredSetMultimap)
2138        ? filterFiltered((FilteredSetMultimap<K, V>) unfiltered, entryPredicate)
2139        : new FilteredEntrySetMultimap<K, V>(checkNotNull(unfiltered), entryPredicate);
2140  }
2141
2142  /**
2143   * Support removal operations when filtering a filtered multimap. Since a filtered multimap has
2144   * iterators that don't support remove, passing one to the FilteredEntryMultimap constructor would
2145   * lead to a multimap whose removal operations would fail. This method combines the predicates to
2146   * avoid that problem.
2147   */
2148  private static <K, V> Multimap<K, V> filterFiltered(
2149      FilteredMultimap<K, V> multimap, Predicate<? super Entry<K, V>> entryPredicate) {
2150    Predicate<Entry<K, V>> predicate =
2151        Predicates.<Entry<K, V>>and(multimap.entryPredicate(), entryPredicate);
2152    return new FilteredEntryMultimap<>(multimap.unfiltered(), predicate);
2153  }
2154
2155  /**
2156   * Support removal operations when filtering a filtered multimap. Since a filtered multimap has
2157   * iterators that don't support remove, passing one to the FilteredEntryMultimap constructor would
2158   * lead to a multimap whose removal operations would fail. This method combines the predicates to
2159   * avoid that problem.
2160   */
2161  private static <K, V> SetMultimap<K, V> filterFiltered(
2162      FilteredSetMultimap<K, V> multimap, Predicate<? super Entry<K, V>> entryPredicate) {
2163    Predicate<Entry<K, V>> predicate =
2164        Predicates.<Entry<K, V>>and(multimap.entryPredicate(), entryPredicate);
2165    return new FilteredEntrySetMultimap<>(multimap.unfiltered(), predicate);
2166  }
2167
2168  static boolean equalsImpl(Multimap<?, ?> multimap, @Nullable Object object) {
2169    if (object == multimap) {
2170      return true;
2171    }
2172    if (object instanceof Multimap) {
2173      Multimap<?, ?> that = (Multimap<?, ?>) object;
2174      return multimap.asMap().equals(that.asMap());
2175    }
2176    return false;
2177  }
2178
2179  // TODO(jlevy): Create methods that filter a SortedSetMultimap.
2180}