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