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