001/*
002 * Copyright (C) 2008 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.google.common.collect;
018
019import static com.google.common.base.Preconditions.checkNotNull;
020import static com.google.common.collect.CollectPreconditions.checkEntryNotNull;
021import static com.google.common.collect.CollectPreconditions.checkNonnegative;
022import static com.google.common.collect.Iterators.emptyIterator;
023import static com.google.common.collect.Maps.immutableEntry;
024import static java.lang.Math.max;
025import static java.util.Arrays.asList;
026import static java.util.Objects.requireNonNull;
027
028import com.google.common.annotations.GwtCompatible;
029import com.google.common.annotations.GwtIncompatible;
030import com.google.common.annotations.J2ktIncompatible;
031import com.google.errorprone.annotations.CanIgnoreReturnValue;
032import com.google.errorprone.annotations.DoNotCall;
033import com.google.errorprone.annotations.DoNotMock;
034import com.google.j2objc.annotations.Weak;
035import com.google.j2objc.annotations.WeakOuter;
036import java.io.InvalidObjectException;
037import java.io.ObjectInputStream;
038import java.io.Serializable;
039import java.util.Collection;
040import java.util.Comparator;
041import java.util.Iterator;
042import java.util.Map;
043import java.util.Map.Entry;
044import java.util.Set;
045import java.util.Spliterator;
046import java.util.function.BiConsumer;
047import javax.annotation.CheckForNull;
048import org.checkerframework.checker.nullness.qual.Nullable;
049
050/**
051 * A {@link Multimap} whose contents will never change, with many other important properties
052 * detailed at {@link ImmutableCollection}.
053 *
054 * <p><b>Warning:</b> avoid <i>direct</i> usage of {@link ImmutableMultimap} as a type (as with
055 * {@link Multimap} itself). Prefer subtypes such as {@link ImmutableSetMultimap} or {@link
056 * ImmutableListMultimap}, which have well-defined {@link #equals} semantics, thus avoiding a common
057 * source of bugs and confusion.
058 *
059 * <p><b>Note:</b> every {@link ImmutableMultimap} offers an {@link #inverse} view, so there is no
060 * need for a distinct {@code ImmutableBiMultimap} type.
061 *
062 * <p><a id="iteration"></a>
063 *
064 * <p><b>Key-grouped iteration.</b> All view collections follow the same iteration order. In all
065 * current implementations, the iteration order always keeps multiple entries with the same key
066 * together. Any creation method that would customarily respect insertion order (such as {@link
067 * #copyOf(Multimap)}) instead preserves key-grouped order by inserting entries for an existing key
068 * immediately after the last entry having that key.
069 *
070 * <p>See the Guava User Guide article on <a href=
071 * "https://github.com/google/guava/wiki/ImmutableCollectionsExplained">immutable collections</a>.
072 *
073 * @author Jared Levy
074 * @since 2.0
075 */
076@GwtCompatible(emulated = true)
077@ElementTypesAreNonnullByDefault
078public abstract class ImmutableMultimap<K, V> extends BaseImmutableMultimap<K, V>
079    implements Serializable {
080
081  /**
082   * Returns an empty multimap.
083   *
084   * <p><b>Performance note:</b> the instance returned is a singleton.
085   */
086  public static <K, V> ImmutableMultimap<K, V> of() {
087    return ImmutableListMultimap.of();
088  }
089
090  /** Returns an immutable multimap containing a single entry. */
091  public static <K, V> ImmutableMultimap<K, V> of(K k1, V v1) {
092    return ImmutableListMultimap.of(k1, v1);
093  }
094
095  /** Returns an immutable multimap containing the given entries, in order. */
096  public static <K, V> ImmutableMultimap<K, V> of(K k1, V v1, K k2, V v2) {
097    return ImmutableListMultimap.of(k1, v1, k2, v2);
098  }
099
100  /**
101   * Returns an immutable multimap containing the given entries, in the "key-grouped" insertion
102   * order described in the <a href="#iteration">class documentation</a>.
103   */
104  public static <K, V> ImmutableMultimap<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3) {
105    return ImmutableListMultimap.of(k1, v1, k2, v2, k3, v3);
106  }
107
108  /**
109   * Returns an immutable multimap containing the given entries, in the "key-grouped" insertion
110   * order described in the <a href="#iteration">class documentation</a>.
111   */
112  public static <K, V> ImmutableMultimap<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
113    return ImmutableListMultimap.of(k1, v1, k2, v2, k3, v3, k4, v4);
114  }
115
116  /**
117   * Returns an immutable multimap containing the given entries, in the "key-grouped" insertion
118   * order described in the <a href="#iteration">class documentation</a>.
119   */
120  public static <K, V> ImmutableMultimap<K, V> of(
121      K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
122    return ImmutableListMultimap.of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5);
123  }
124
125  // looking for of() with > 5 entries? Use the builder instead.
126
127  /**
128   * Returns a new builder. The generated builder is equivalent to the builder created by the {@link
129   * Builder} constructor.
130   */
131  public static <K, V> Builder<K, V> builder() {
132    return new Builder<>();
133  }
134
135  /**
136   * Returns a new builder with a hint for how many distinct keys are expected to be added. The
137   * generated builder is equivalent to that returned by {@link #builder}, but may perform better if
138   * {@code expectedKeys} is a good estimate.
139   *
140   * @throws IllegalArgumentException if {@code expectedKeys} is negative
141   * @since 33.3.0
142   */
143  public static <K, V> Builder<K, V> builderWithExpectedKeys(int expectedKeys) {
144    checkNonnegative(expectedKeys, "expectedKeys");
145    return new Builder<>(expectedKeys);
146  }
147
148  /**
149   * A builder for creating immutable multimap instances, especially {@code public static final}
150   * multimaps ("constant multimaps"). Example:
151   *
152   * <pre>{@code
153   * static final Multimap<String, Integer> STRING_TO_INTEGER_MULTIMAP =
154   *     new ImmutableMultimap.Builder<String, Integer>()
155   *         .put("one", 1)
156   *         .putAll("several", 1, 2, 3)
157   *         .putAll("many", 1, 2, 3, 4, 5)
158   *         .build();
159   * }</pre>
160   *
161   * <p>Builder instances can be reused; it is safe to call {@link #build} multiple times to build
162   * multiple multimaps in series. Each multimap contains the key-value mappings in the previously
163   * created multimaps.
164   *
165   * @since 2.0
166   */
167  @DoNotMock
168  public static class Builder<K, V> {
169    @CheckForNull Map<K, ImmutableCollection.Builder<V>> builderMap;
170    @CheckForNull Comparator<? super K> keyComparator;
171    @CheckForNull Comparator<? super V> valueComparator;
172    int expectedValuesPerKey = ImmutableCollection.Builder.DEFAULT_INITIAL_CAPACITY;
173
174    /**
175     * Creates a new builder. The returned builder is equivalent to the builder generated by {@link
176     * ImmutableMultimap#builder}.
177     */
178    public Builder() {}
179
180    /** Creates a new builder with a hint for the number of distinct keys. */
181    Builder(int expectedKeys) {
182      if (expectedKeys > 0) {
183        builderMap = Platform.preservesInsertionOrderOnPutsMapWithExpectedSize(expectedKeys);
184      }
185      // otherwise, leave it null to be constructed lazily
186    }
187
188    Map<K, ImmutableCollection.Builder<V>> ensureBuilderMapNonNull() {
189      Map<K, ImmutableCollection.Builder<V>> result = builderMap;
190      if (result == null) {
191        result = Platform.preservesInsertionOrderOnPutsMap();
192        builderMap = result;
193      }
194      return result;
195    }
196
197    ImmutableCollection.Builder<V> newValueCollectionBuilderWithExpectedSize(int expectedSize) {
198      return ImmutableList.builderWithExpectedSize(expectedSize);
199    }
200
201    /**
202     * Provides a hint for how many values will be associated with each key newly added to the
203     * builder after this call. This does not change semantics, but may improve performance if
204     * {@code expectedValuesPerKey} is a good estimate.
205     *
206     * <p>This may be called more than once; each newly added key will use the most recent call to
207     * {@link #expectedValuesPerKey} as its hint.
208     *
209     * @throws IllegalArgumentException if {@code expectedValuesPerKey} is negative
210     * @since 33.3.0
211     */
212    @CanIgnoreReturnValue
213    public Builder<K, V> expectedValuesPerKey(int expectedValuesPerKey) {
214      checkNonnegative(expectedValuesPerKey, "expectedValuesPerKey");
215
216      // Always presize to at least 1, since we only bother creating a value collection if there's
217      // at least one element.
218      this.expectedValuesPerKey = max(expectedValuesPerKey, 1);
219
220      return this;
221    }
222
223    /**
224     * By default, if we are handed a value collection bigger than expectedValuesPerKey, presize to
225     * accept that many elements.
226     *
227     * <p>This gets overridden in ImmutableSetMultimap.Builder to only trust the size of {@code
228     * values} if it is a Set and therefore probably already deduplicated.
229     */
230    int expectedValueCollectionSize(int defaultExpectedValues, Iterable<?> values) {
231      if (values instanceof Collection<?>) {
232        Collection<?> collection = (Collection<?>) values;
233        return max(defaultExpectedValues, collection.size());
234      } else {
235        return defaultExpectedValues;
236      }
237    }
238
239    /** Adds a key-value mapping to the built multimap. */
240    @CanIgnoreReturnValue
241    public Builder<K, V> put(K key, V value) {
242      checkEntryNotNull(key, value);
243      ImmutableCollection.Builder<V> valuesBuilder = ensureBuilderMapNonNull().get(key);
244      if (valuesBuilder == null) {
245        valuesBuilder = newValueCollectionBuilderWithExpectedSize(expectedValuesPerKey);
246        ensureBuilderMapNonNull().put(key, valuesBuilder);
247      }
248      valuesBuilder.add(value);
249      return this;
250    }
251
252    /**
253     * Adds an entry to the built multimap.
254     *
255     * @since 11.0
256     */
257    @CanIgnoreReturnValue
258    public Builder<K, V> put(Entry<? extends K, ? extends V> entry) {
259      return put(entry.getKey(), entry.getValue());
260    }
261
262    /**
263     * Adds entries to the built multimap.
264     *
265     * @since 19.0
266     */
267    @CanIgnoreReturnValue
268    public Builder<K, V> putAll(Iterable<? extends Entry<? extends K, ? extends V>> entries) {
269      for (Entry<? extends K, ? extends V> entry : entries) {
270        put(entry);
271      }
272      return this;
273    }
274
275    /**
276     * Stores a collection of values with the same key in the built multimap.
277     *
278     * @throws NullPointerException if {@code key}, {@code values}, or any element in {@code values}
279     *     is null. The builder is left in an invalid state.
280     */
281    @CanIgnoreReturnValue
282    public Builder<K, V> putAll(K key, Iterable<? extends V> values) {
283      if (key == null) {
284        throw new NullPointerException("null key in entry: null=" + Iterables.toString(values));
285      }
286      Iterator<? extends V> valuesItr = values.iterator();
287      if (!valuesItr.hasNext()) {
288        return this;
289      }
290      ImmutableCollection.Builder<V> valuesBuilder = ensureBuilderMapNonNull().get(key);
291      if (valuesBuilder == null) {
292        valuesBuilder =
293            newValueCollectionBuilderWithExpectedSize(
294                expectedValueCollectionSize(expectedValuesPerKey, values));
295        ensureBuilderMapNonNull().put(key, valuesBuilder);
296      }
297      while (valuesItr.hasNext()) {
298        V value = valuesItr.next();
299        checkEntryNotNull(key, value);
300        valuesBuilder.add(value);
301      }
302      return this;
303    }
304
305    /**
306     * Stores an array of values with the same key in the built multimap.
307     *
308     * @throws NullPointerException if the key or any value is null. The builder is left in an
309     *     invalid state.
310     */
311    @CanIgnoreReturnValue
312    public Builder<K, V> putAll(K key, V... values) {
313      return putAll(key, asList(values));
314    }
315
316    /**
317     * Stores another multimap's entries in the built multimap. The generated multimap's key and
318     * value orderings correspond to the iteration ordering of the {@code multimap.asMap()} view,
319     * with new keys and values following any existing keys and values.
320     *
321     * @throws NullPointerException if any key or value in {@code multimap} is null. The builder is
322     *     left in an invalid state.
323     */
324    @CanIgnoreReturnValue
325    public Builder<K, V> putAll(Multimap<? extends K, ? extends V> multimap) {
326      for (Entry<? extends K, ? extends Collection<? extends V>> entry :
327          multimap.asMap().entrySet()) {
328        putAll(entry.getKey(), entry.getValue());
329      }
330      return this;
331    }
332
333    /**
334     * Specifies the ordering of the generated multimap's keys.
335     *
336     * @since 8.0
337     */
338    @CanIgnoreReturnValue
339    public Builder<K, V> orderKeysBy(Comparator<? super K> keyComparator) {
340      this.keyComparator = checkNotNull(keyComparator);
341      return this;
342    }
343
344    /**
345     * Specifies the ordering of the generated multimap's values for each key.
346     *
347     * @since 8.0
348     */
349    @CanIgnoreReturnValue
350    public Builder<K, V> orderValuesBy(Comparator<? super V> valueComparator) {
351      this.valueComparator = checkNotNull(valueComparator);
352      return this;
353    }
354
355    @CanIgnoreReturnValue
356    Builder<K, V> combine(Builder<K, V> other) {
357      if (other.builderMap != null) {
358        for (Map.Entry<K, ImmutableCollection.Builder<V>> entry : other.builderMap.entrySet()) {
359          putAll(entry.getKey(), entry.getValue().build());
360        }
361      }
362      return this;
363    }
364
365    /** Returns a newly-created immutable multimap. */
366    public ImmutableMultimap<K, V> build() {
367      if (builderMap == null) {
368        return ImmutableListMultimap.of();
369      }
370      Collection<Map.Entry<K, ImmutableCollection.Builder<V>>> mapEntries = builderMap.entrySet();
371      if (keyComparator != null) {
372        mapEntries = Ordering.from(keyComparator).<K>onKeys().immutableSortedCopy(mapEntries);
373      }
374      return ImmutableListMultimap.fromMapBuilderEntries(mapEntries, valueComparator);
375    }
376  }
377
378  /**
379   * Returns an immutable multimap containing the same mappings as {@code multimap}, in the
380   * "key-grouped" iteration order described in the class documentation.
381   *
382   * <p>Despite the method name, this method attempts to avoid actually copying the data when it is
383   * safe to do so. The exact circumstances under which a copy will or will not be performed are
384   * undocumented and subject to change.
385   *
386   * @throws NullPointerException if any key or value in {@code multimap} is null
387   */
388  public static <K, V> ImmutableMultimap<K, V> copyOf(Multimap<? extends K, ? extends V> multimap) {
389    if (multimap instanceof ImmutableMultimap) {
390      @SuppressWarnings("unchecked") // safe since multimap is not writable
391      ImmutableMultimap<K, V> kvMultimap = (ImmutableMultimap<K, V>) multimap;
392      if (!kvMultimap.isPartialView()) {
393        return kvMultimap;
394      }
395    }
396    return ImmutableListMultimap.copyOf(multimap);
397  }
398
399  /**
400   * Returns an immutable multimap containing the specified entries. The returned multimap iterates
401   * over keys in the order they were first encountered in the input, and the values for each key
402   * are iterated in the order they were encountered.
403   *
404   * @throws NullPointerException if any key, value, or entry is null
405   * @since 19.0
406   */
407  public static <K, V> ImmutableMultimap<K, V> copyOf(
408      Iterable<? extends Entry<? extends K, ? extends V>> entries) {
409    return ImmutableListMultimap.copyOf(entries);
410  }
411
412  final transient ImmutableMap<K, ? extends ImmutableCollection<V>> map;
413  final transient int size;
414
415  // These constants allow the deserialization code to set final fields. This
416  // holder class makes sure they are not initialized unless an instance is
417  // deserialized.
418  @GwtIncompatible // java serialization is not supported
419  @J2ktIncompatible
420  static class FieldSettersHolder {
421    static final Serialization.FieldSetter<? super ImmutableMultimap<?, ?>> MAP_FIELD_SETTER =
422        Serialization.getFieldSetter(ImmutableMultimap.class, "map");
423    static final Serialization.FieldSetter<? super ImmutableMultimap<?, ?>> SIZE_FIELD_SETTER =
424        Serialization.getFieldSetter(ImmutableMultimap.class, "size");
425  }
426
427  ImmutableMultimap(ImmutableMap<K, ? extends ImmutableCollection<V>> map, int size) {
428    this.map = map;
429    this.size = size;
430  }
431
432  // mutators (not supported)
433
434  /**
435   * Guaranteed to throw an exception and leave the multimap unmodified.
436   *
437   * @throws UnsupportedOperationException always
438   * @deprecated Unsupported operation.
439   */
440  @CanIgnoreReturnValue
441  @Deprecated
442  @Override
443  @DoNotCall("Always throws UnsupportedOperationException")
444  // DoNotCall wants this to be final, but we want to override it to return more specific types.
445  // Inheritance is closed, and all subtypes are @DoNotCall, so this is safe to suppress.
446  @SuppressWarnings("DoNotCall")
447  public ImmutableCollection<V> removeAll(@CheckForNull Object key) {
448    throw new UnsupportedOperationException();
449  }
450
451  /**
452   * Guaranteed to throw an exception and leave the multimap unmodified.
453   *
454   * @throws UnsupportedOperationException always
455   * @deprecated Unsupported operation.
456   */
457  @CanIgnoreReturnValue
458  @Deprecated
459  @Override
460  @DoNotCall("Always throws UnsupportedOperationException")
461  // DoNotCall wants this to be final, but we want to override it to return more specific types.
462  // Inheritance is closed, and all subtypes are @DoNotCall, so this is safe to suppress.
463  @SuppressWarnings("DoNotCall")
464  public ImmutableCollection<V> replaceValues(K key, Iterable<? extends V> values) {
465    throw new UnsupportedOperationException();
466  }
467
468  /**
469   * Guaranteed to throw an exception and leave the multimap unmodified.
470   *
471   * @throws UnsupportedOperationException always
472   * @deprecated Unsupported operation.
473   */
474  @Deprecated
475  @Override
476  @DoNotCall("Always throws UnsupportedOperationException")
477  public final void clear() {
478    throw new UnsupportedOperationException();
479  }
480
481  /**
482   * Returns an immutable collection of the values for the given key. If no mappings in the multimap
483   * have the provided key, an empty immutable collection is returned. The values are in the same
484   * order as the parameters used to build this multimap.
485   */
486  @Override
487  public abstract ImmutableCollection<V> get(K key);
488
489  /**
490   * Returns an immutable multimap which is the inverse of this one. For every key-value mapping in
491   * the original, the result will have a mapping with key and value reversed.
492   *
493   * @since 11.0
494   */
495  public abstract ImmutableMultimap<V, K> inverse();
496
497  /**
498   * Guaranteed to throw an exception and leave the multimap unmodified.
499   *
500   * @throws UnsupportedOperationException always
501   * @deprecated Unsupported operation.
502   */
503  @CanIgnoreReturnValue
504  @Deprecated
505  @Override
506  @DoNotCall("Always throws UnsupportedOperationException")
507  public final boolean put(K key, V value) {
508    throw new UnsupportedOperationException();
509  }
510
511  /**
512   * Guaranteed to throw an exception and leave the multimap unmodified.
513   *
514   * @throws UnsupportedOperationException always
515   * @deprecated Unsupported operation.
516   */
517  @CanIgnoreReturnValue
518  @Deprecated
519  @Override
520  @DoNotCall("Always throws UnsupportedOperationException")
521  public final boolean putAll(K key, Iterable<? extends V> values) {
522    throw new UnsupportedOperationException();
523  }
524
525  /**
526   * Guaranteed to throw an exception and leave the multimap unmodified.
527   *
528   * @throws UnsupportedOperationException always
529   * @deprecated Unsupported operation.
530   */
531  @CanIgnoreReturnValue
532  @Deprecated
533  @Override
534  @DoNotCall("Always throws UnsupportedOperationException")
535  public final boolean putAll(Multimap<? extends K, ? extends V> multimap) {
536    throw new UnsupportedOperationException();
537  }
538
539  /**
540   * Guaranteed to throw an exception and leave the multimap unmodified.
541   *
542   * @throws UnsupportedOperationException always
543   * @deprecated Unsupported operation.
544   */
545  @CanIgnoreReturnValue
546  @Deprecated
547  @Override
548  @DoNotCall("Always throws UnsupportedOperationException")
549  public final boolean remove(@CheckForNull Object key, @CheckForNull Object value) {
550    throw new UnsupportedOperationException();
551  }
552
553  /**
554   * Returns {@code true} if this immutable multimap's implementation contains references to
555   * user-created objects that aren't accessible via this multimap's methods. This is generally used
556   * to determine whether {@code copyOf} implementations should make an explicit copy to avoid
557   * memory leaks.
558   */
559  boolean isPartialView() {
560    return map.isPartialView();
561  }
562
563  // accessors
564
565  @Override
566  public boolean containsKey(@CheckForNull Object key) {
567    return map.containsKey(key);
568  }
569
570  @Override
571  public boolean containsValue(@CheckForNull Object value) {
572    return value != null && super.containsValue(value);
573  }
574
575  @Override
576  public int size() {
577    return size;
578  }
579
580  // views
581
582  /**
583   * Returns an immutable set of the distinct keys in this multimap, in the same order as they
584   * appear in this multimap.
585   */
586  @Override
587  public ImmutableSet<K> keySet() {
588    return map.keySet();
589  }
590
591  @Override
592  Set<K> createKeySet() {
593    throw new AssertionError("unreachable");
594  }
595
596  /**
597   * Returns an immutable map that associates each key with its corresponding values in the
598   * multimap. Keys and values appear in the same order as in this multimap.
599   */
600  @Override
601  @SuppressWarnings("unchecked") // a widening cast
602  public ImmutableMap<K, Collection<V>> asMap() {
603    return (ImmutableMap) map;
604  }
605
606  @Override
607  Map<K, Collection<V>> createAsMap() {
608    throw new AssertionError("should never be called");
609  }
610
611  /** Returns an immutable collection of all key-value pairs in the multimap. */
612  @Override
613  public ImmutableCollection<Entry<K, V>> entries() {
614    return (ImmutableCollection<Entry<K, V>>) super.entries();
615  }
616
617  @Override
618  ImmutableCollection<Entry<K, V>> createEntries() {
619    return new EntryCollection<>(this);
620  }
621
622  private static class EntryCollection<K, V> extends ImmutableCollection<Entry<K, V>> {
623    @Weak final ImmutableMultimap<K, V> multimap;
624
625    EntryCollection(ImmutableMultimap<K, V> multimap) {
626      this.multimap = multimap;
627    }
628
629    @Override
630    public UnmodifiableIterator<Entry<K, V>> iterator() {
631      return multimap.entryIterator();
632    }
633
634    @Override
635    boolean isPartialView() {
636      return multimap.isPartialView();
637    }
638
639    @Override
640    public int size() {
641      return multimap.size();
642    }
643
644    @Override
645    public boolean contains(@CheckForNull Object object) {
646      if (object instanceof Entry) {
647        Entry<?, ?> entry = (Entry<?, ?>) object;
648        return multimap.containsEntry(entry.getKey(), entry.getValue());
649      }
650      return false;
651    }
652
653    // redeclare to help optimizers with b/310253115
654    @SuppressWarnings("RedundantOverride")
655    @Override
656    @J2ktIncompatible // serialization
657    @GwtIncompatible // serialization
658    Object writeReplace() {
659      return super.writeReplace();
660    }
661
662    private static final long serialVersionUID = 0;
663  }
664
665  @Override
666  UnmodifiableIterator<Entry<K, V>> entryIterator() {
667    return new UnmodifiableIterator<Entry<K, V>>() {
668      final Iterator<? extends Entry<K, ? extends ImmutableCollection<V>>> asMapItr =
669          map.entrySet().iterator();
670      @CheckForNull K currentKey = null;
671      Iterator<V> valueItr = emptyIterator();
672
673      @Override
674      public boolean hasNext() {
675        return valueItr.hasNext() || asMapItr.hasNext();
676      }
677
678      @Override
679      public Entry<K, V> next() {
680        if (!valueItr.hasNext()) {
681          Entry<K, ? extends ImmutableCollection<V>> entry = asMapItr.next();
682          currentKey = entry.getKey();
683          valueItr = entry.getValue().iterator();
684        }
685        /*
686         * requireNonNull is safe: The first call to this method always enters the !hasNext() case
687         * and populates currentKey, after which it's never cleared.
688         */
689        return immutableEntry(requireNonNull(currentKey), valueItr.next());
690      }
691    };
692  }
693
694  @Override
695  Spliterator<Entry<K, V>> entrySpliterator() {
696    return CollectSpliterators.flatMap(
697        asMap().entrySet().spliterator(),
698        keyToValueCollectionEntry -> {
699          K key = keyToValueCollectionEntry.getKey();
700          Collection<V> valueCollection = keyToValueCollectionEntry.getValue();
701          return CollectSpliterators.map(
702              valueCollection.spliterator(), (V value) -> immutableEntry(key, value));
703        },
704        Spliterator.SIZED | (this instanceof SetMultimap ? Spliterator.DISTINCT : 0),
705        size());
706  }
707
708  @Override
709  public void forEach(BiConsumer<? super K, ? super V> action) {
710    checkNotNull(action);
711    asMap()
712        .forEach(
713            (key, valueCollection) -> valueCollection.forEach(value -> action.accept(key, value)));
714  }
715
716  /**
717   * Returns an immutable multiset containing all the keys in this multimap, in the same order and
718   * with the same frequencies as they appear in this multimap; to get only a single occurrence of
719   * each key, use {@link #keySet}.
720   */
721  @Override
722  public ImmutableMultiset<K> keys() {
723    return (ImmutableMultiset<K>) super.keys();
724  }
725
726  @Override
727  ImmutableMultiset<K> createKeys() {
728    return new Keys();
729  }
730
731  @SuppressWarnings("serial") // Uses writeReplace, not default serialization
732  @WeakOuter
733  class Keys extends ImmutableMultiset<K> {
734    @Override
735    public boolean contains(@CheckForNull Object object) {
736      return containsKey(object);
737    }
738
739    @Override
740    public int count(@CheckForNull Object element) {
741      Collection<V> values = map.get(element);
742      return (values == null) ? 0 : values.size();
743    }
744
745    @Override
746    public ImmutableSet<K> elementSet() {
747      return keySet();
748    }
749
750    @Override
751    public int size() {
752      return ImmutableMultimap.this.size();
753    }
754
755    @Override
756    Multiset.Entry<K> getEntry(int index) {
757      Map.Entry<K, ? extends Collection<V>> entry = map.entrySet().asList().get(index);
758      return Multisets.immutableEntry(entry.getKey(), entry.getValue().size());
759    }
760
761    @Override
762    boolean isPartialView() {
763      return true;
764    }
765
766    @GwtIncompatible
767    @J2ktIncompatible
768    @Override
769    Object writeReplace() {
770      return new KeysSerializedForm(ImmutableMultimap.this);
771    }
772
773    @GwtIncompatible
774    @J2ktIncompatible
775    private void readObject(ObjectInputStream stream) throws InvalidObjectException {
776      throw new InvalidObjectException("Use KeysSerializedForm");
777    }
778  }
779
780  @GwtIncompatible
781  @J2ktIncompatible
782  private static final class KeysSerializedForm implements Serializable {
783    final ImmutableMultimap<?, ?> multimap;
784
785    KeysSerializedForm(ImmutableMultimap<?, ?> multimap) {
786      this.multimap = multimap;
787    }
788
789    Object readResolve() {
790      return multimap.keys();
791    }
792  }
793
794  /**
795   * Returns an immutable collection of the values in this multimap. Its iterator traverses the
796   * values for the first key, the values for the second key, and so on.
797   */
798  @Override
799  public ImmutableCollection<V> values() {
800    return (ImmutableCollection<V>) super.values();
801  }
802
803  @Override
804  ImmutableCollection<V> createValues() {
805    return new Values<>(this);
806  }
807
808  @Override
809  UnmodifiableIterator<V> valueIterator() {
810    return new UnmodifiableIterator<V>() {
811      Iterator<? extends ImmutableCollection<V>> valueCollectionItr = map.values().iterator();
812      Iterator<V> valueItr = emptyIterator();
813
814      @Override
815      public boolean hasNext() {
816        return valueItr.hasNext() || valueCollectionItr.hasNext();
817      }
818
819      @Override
820      public V next() {
821        if (!valueItr.hasNext()) {
822          valueItr = valueCollectionItr.next().iterator();
823        }
824        return valueItr.next();
825      }
826    };
827  }
828
829  private static final class Values<K, V> extends ImmutableCollection<V> {
830    @Weak private final transient ImmutableMultimap<K, V> multimap;
831
832    Values(ImmutableMultimap<K, V> multimap) {
833      this.multimap = multimap;
834    }
835
836    @Override
837    public boolean contains(@CheckForNull Object object) {
838      return multimap.containsValue(object);
839    }
840
841    @Override
842    public UnmodifiableIterator<V> iterator() {
843      return multimap.valueIterator();
844    }
845
846    @GwtIncompatible // not present in emulated superclass
847    @Override
848    int copyIntoArray(@Nullable Object[] dst, int offset) {
849      for (ImmutableCollection<V> valueCollection : multimap.map.values()) {
850        offset = valueCollection.copyIntoArray(dst, offset);
851      }
852      return offset;
853    }
854
855    @Override
856    public int size() {
857      return multimap.size();
858    }
859
860    @Override
861    boolean isPartialView() {
862      return true;
863    }
864
865    // redeclare to help optimizers with b/310253115
866    @SuppressWarnings("RedundantOverride")
867    @Override
868    @J2ktIncompatible // serialization
869    @GwtIncompatible // serialization
870    Object writeReplace() {
871      return super.writeReplace();
872    }
873
874    @J2ktIncompatible // serialization
875    private static final long serialVersionUID = 0;
876  }
877
878  @J2ktIncompatible // serialization
879  private static final long serialVersionUID = 0;
880}