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.base.Preconditions.checkState;
021import static com.google.common.collect.CollectPreconditions.checkEntryNotNull;
022import static com.google.common.collect.CollectPreconditions.checkNonnegative;
023import static java.util.Objects.requireNonNull;
024
025import com.google.common.annotations.Beta;
026import com.google.common.annotations.GwtCompatible;
027import com.google.common.annotations.VisibleForTesting;
028import com.google.errorprone.annotations.CanIgnoreReturnValue;
029import com.google.errorprone.annotations.DoNotCall;
030import com.google.errorprone.annotations.DoNotMock;
031import com.google.errorprone.annotations.concurrent.LazyInit;
032import com.google.j2objc.annotations.RetainedWith;
033import com.google.j2objc.annotations.WeakOuter;
034import java.io.Serializable;
035import java.util.AbstractMap;
036import java.util.Arrays;
037import java.util.Collection;
038import java.util.Collections;
039import java.util.Comparator;
040import java.util.EnumMap;
041import java.util.Iterator;
042import java.util.Map;
043import java.util.SortedMap;
044import java.util.Spliterator;
045import java.util.Spliterators;
046import java.util.function.BiFunction;
047import java.util.function.BinaryOperator;
048import java.util.function.Function;
049import java.util.stream.Collector;
050import java.util.stream.Collectors;
051import javax.annotation.CheckForNull;
052import org.checkerframework.checker.nullness.qual.Nullable;
053
054/**
055 * A {@link Map} whose contents will never change, with many other important properties detailed at
056 * {@link ImmutableCollection}.
057 *
058 * <p>See the Guava User Guide article on <a href=
059 * "https://github.com/google/guava/wiki/ImmutableCollectionsExplained"> immutable collections</a>.
060 *
061 * @author Jesse Wilson
062 * @author Kevin Bourrillion
063 * @since 2.0
064 */
065@DoNotMock("Use ImmutableMap.of or another implementation")
066@GwtCompatible(serializable = true, emulated = true)
067@SuppressWarnings("serial") // we're overriding default serialization
068@ElementTypesAreNonnullByDefault
069public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable {
070
071  /**
072   * Returns a {@link Collector} that accumulates elements into an {@code ImmutableMap} whose keys
073   * and values are the result of applying the provided mapping functions to the input elements.
074   * Entries appear in the result {@code ImmutableMap} in encounter order.
075   *
076   * <p>If the mapped keys contain duplicates (according to {@link Object#equals(Object)}, an {@code
077   * IllegalArgumentException} is thrown when the collection operation is performed. (This differs
078   * from the {@code Collector} returned by {@link Collectors#toMap(Function, Function)}, which
079   * throws an {@code IllegalStateException}.)
080   *
081   * @since 21.0
082   */
083  public static <T extends @Nullable Object, K, V>
084      Collector<T, ?, ImmutableMap<K, V>> toImmutableMap(
085          Function<? super T, ? extends K> keyFunction,
086          Function<? super T, ? extends V> valueFunction) {
087    return CollectCollectors.toImmutableMap(keyFunction, valueFunction);
088  }
089
090  /**
091   * Returns a {@link Collector} that accumulates elements into an {@code ImmutableMap} whose keys
092   * and values are the result of applying the provided mapping functions to the input elements.
093   *
094   * <p>If the mapped keys contain duplicates (according to {@link Object#equals(Object)}), the
095   * values are merged using the specified merging function. Entries will appear in the encounter
096   * order of the first occurrence of the key.
097   *
098   * @since 21.0
099   */
100  public static <T extends @Nullable Object, K, V>
101      Collector<T, ?, ImmutableMap<K, V>> toImmutableMap(
102          Function<? super T, ? extends K> keyFunction,
103          Function<? super T, ? extends V> valueFunction,
104          BinaryOperator<V> mergeFunction) {
105    return CollectCollectors.toImmutableMap(keyFunction, valueFunction, mergeFunction);
106  }
107
108  /**
109   * Returns the empty map. This map behaves and performs comparably to {@link
110   * Collections#emptyMap}, and is preferable mainly for consistency and maintainability of your
111   * code.
112   *
113   * <p><b>Performance note:</b> the instance returned is a singleton.
114   */
115  @SuppressWarnings("unchecked")
116  public static <K, V> ImmutableMap<K, V> of() {
117    return (ImmutableMap<K, V>) RegularImmutableMap.EMPTY;
118  }
119
120  /**
121   * Returns an immutable map containing a single entry. This map behaves and performs comparably to
122   * {@link Collections#singletonMap} but will not accept a null key or value. It is preferable
123   * mainly for consistency and maintainability of your code.
124   */
125  public static <K, V> ImmutableMap<K, V> of(K k1, V v1) {
126    return ImmutableBiMap.of(k1, v1);
127  }
128
129  /**
130   * Returns an immutable map containing the given entries, in order.
131   *
132   * @throws IllegalArgumentException if duplicate keys are provided
133   */
134  public static <K, V> ImmutableMap<K, V> of(K k1, V v1, K k2, V v2) {
135    return RegularImmutableMap.fromEntries(entryOf(k1, v1), entryOf(k2, v2));
136  }
137
138  /**
139   * Returns an immutable map containing the given entries, in order.
140   *
141   * @throws IllegalArgumentException if duplicate keys are provided
142   */
143  public static <K, V> ImmutableMap<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3) {
144    return RegularImmutableMap.fromEntries(entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3));
145  }
146
147  /**
148   * Returns an immutable map containing the given entries, in order.
149   *
150   * @throws IllegalArgumentException if duplicate keys are provided
151   */
152  public static <K, V> ImmutableMap<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
153    return RegularImmutableMap.fromEntries(
154        entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3), entryOf(k4, v4));
155  }
156
157  /**
158   * Returns an immutable map containing the given entries, in order.
159   *
160   * @throws IllegalArgumentException if duplicate keys are provided
161   */
162  public static <K, V> ImmutableMap<K, V> of(
163      K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
164    return RegularImmutableMap.fromEntries(
165        entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3), entryOf(k4, v4), entryOf(k5, v5));
166  }
167
168  /**
169   * Returns an immutable map containing the given entries, in order.
170   *
171   * @throws IllegalArgumentException if duplicate keys are provided
172   * @since 31.0
173   */
174  public static <K, V> ImmutableMap<K, V> of(
175      K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6) {
176    return RegularImmutableMap.fromEntries(
177        entryOf(k1, v1),
178        entryOf(k2, v2),
179        entryOf(k3, v3),
180        entryOf(k4, v4),
181        entryOf(k5, v5),
182        entryOf(k6, v6));
183  }
184
185  /**
186   * Returns an immutable map containing the given entries, in order.
187   *
188   * @throws IllegalArgumentException if duplicate keys are provided
189   * @since 31.0
190   */
191  public static <K, V> ImmutableMap<K, V> of(
192      K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7) {
193    return RegularImmutableMap.fromEntries(
194        entryOf(k1, v1),
195        entryOf(k2, v2),
196        entryOf(k3, v3),
197        entryOf(k4, v4),
198        entryOf(k5, v5),
199        entryOf(k6, v6),
200        entryOf(k7, v7));
201  }
202
203  /**
204   * Returns an immutable map containing the given entries, in order.
205   *
206   * @throws IllegalArgumentException if duplicate keys are provided
207   * @since 31.0
208   */
209  public static <K, V> ImmutableMap<K, V> of(
210      K k1,
211      V v1,
212      K k2,
213      V v2,
214      K k3,
215      V v3,
216      K k4,
217      V v4,
218      K k5,
219      V v5,
220      K k6,
221      V v6,
222      K k7,
223      V v7,
224      K k8,
225      V v8) {
226    return RegularImmutableMap.fromEntries(
227        entryOf(k1, v1),
228        entryOf(k2, v2),
229        entryOf(k3, v3),
230        entryOf(k4, v4),
231        entryOf(k5, v5),
232        entryOf(k6, v6),
233        entryOf(k7, v7),
234        entryOf(k8, v8));
235  }
236
237  /**
238   * Returns an immutable map containing the given entries, in order.
239   *
240   * @throws IllegalArgumentException if duplicate keys are provided
241   * @since 31.0
242   */
243  public static <K, V> ImmutableMap<K, V> of(
244      K k1,
245      V v1,
246      K k2,
247      V v2,
248      K k3,
249      V v3,
250      K k4,
251      V v4,
252      K k5,
253      V v5,
254      K k6,
255      V v6,
256      K k7,
257      V v7,
258      K k8,
259      V v8,
260      K k9,
261      V v9) {
262    return RegularImmutableMap.fromEntries(
263        entryOf(k1, v1),
264        entryOf(k2, v2),
265        entryOf(k3, v3),
266        entryOf(k4, v4),
267        entryOf(k5, v5),
268        entryOf(k6, v6),
269        entryOf(k7, v7),
270        entryOf(k8, v8),
271        entryOf(k9, v9));
272  }
273
274  /**
275   * Returns an immutable map containing the given entries, in order.
276   *
277   * @throws IllegalArgumentException if duplicate keys are provided
278   * @since 31.0
279   */
280  public static <K, V> ImmutableMap<K, V> of(
281      K k1,
282      V v1,
283      K k2,
284      V v2,
285      K k3,
286      V v3,
287      K k4,
288      V v4,
289      K k5,
290      V v5,
291      K k6,
292      V v6,
293      K k7,
294      V v7,
295      K k8,
296      V v8,
297      K k9,
298      V v9,
299      K k10,
300      V v10) {
301    return RegularImmutableMap.fromEntries(
302        entryOf(k1, v1),
303        entryOf(k2, v2),
304        entryOf(k3, v3),
305        entryOf(k4, v4),
306        entryOf(k5, v5),
307        entryOf(k6, v6),
308        entryOf(k7, v7),
309        entryOf(k8, v8),
310        entryOf(k9, v9),
311        entryOf(k10, v10));
312  }
313
314  // looking for of() with > 10 entries? Use the builder or ofEntries instead.
315
316  /**
317   * Returns an immutable map containing the given entries, in order.
318   *
319   * @throws IllegalArgumentException if duplicate keys are provided
320   * @since 31.0
321   */
322  @SafeVarargs
323  public static <K, V> ImmutableMap<K, V> ofEntries(Entry<? extends K, ? extends V>... entries) {
324    @SuppressWarnings("unchecked") // we will only ever read these
325    Entry<K, V>[] entries2 = (Entry<K, V>[]) entries;
326    return RegularImmutableMap.fromEntries(entries2);
327  }
328
329  /**
330   * Verifies that {@code key} and {@code value} are non-null, and returns a new immutable entry
331   * with those values.
332   *
333   * <p>A call to {@link Entry#setValue} on the returned entry will always throw {@link
334   * UnsupportedOperationException}.
335   */
336  static <K, V> Entry<K, V> entryOf(K key, V value) {
337    checkEntryNotNull(key, value);
338    return new AbstractMap.SimpleImmutableEntry<>(key, value);
339  }
340
341  /**
342   * Returns a new builder. The generated builder is equivalent to the builder created by the {@link
343   * Builder} constructor.
344   */
345  public static <K, V> Builder<K, V> builder() {
346    return new Builder<>();
347  }
348
349  /**
350   * Returns a new builder, expecting the specified number of entries to be added.
351   *
352   * <p>If {@code expectedSize} is exactly the number of entries added to the builder before {@link
353   * Builder#build} is called, the builder is likely to perform better than an unsized {@link
354   * #builder()} would have.
355   *
356   * <p>It is not specified if any performance benefits apply if {@code expectedSize} is close to,
357   * but not exactly, the number of entries added to the builder.
358   *
359   * @since 23.1
360   */
361  @Beta
362  public static <K, V> Builder<K, V> builderWithExpectedSize(int expectedSize) {
363    checkNonnegative(expectedSize, "expectedSize");
364    return new Builder<>(expectedSize);
365  }
366
367  static void checkNoConflict(
368      boolean safe, String conflictDescription, Entry<?, ?> entry1, Entry<?, ?> entry2) {
369    if (!safe) {
370      throw conflictException(conflictDescription, entry1, entry2);
371    }
372  }
373
374  static IllegalArgumentException conflictException(
375      String conflictDescription, Object entry1, Object entry2) {
376    return new IllegalArgumentException(
377        "Multiple entries with same " + conflictDescription + ": " + entry1 + " and " + entry2);
378  }
379
380  /**
381   * A builder for creating immutable map instances, especially {@code public static final} maps
382   * ("constant maps"). Example:
383   *
384   * <pre>{@code
385   * static final ImmutableMap<String, Integer> WORD_TO_INT =
386   *     new ImmutableMap.Builder<String, Integer>()
387   *         .put("one", 1)
388   *         .put("two", 2)
389   *         .put("three", 3)
390   *         .buildOrThrow();
391   * }</pre>
392   *
393   * <p>For <i>small</i> immutable maps, the {@code ImmutableMap.of()} methods are even more
394   * convenient.
395   *
396   * <p>By default, a {@code Builder} will generate maps that iterate over entries in the order they
397   * were inserted into the builder, equivalently to {@code LinkedHashMap}. For example, in the
398   * above example, {@code WORD_TO_INT.entrySet()} is guaranteed to iterate over the entries in the
399   * order {@code "one"=1, "two"=2, "three"=3}, and {@code keySet()} and {@code values()} respect
400   * the same order. If you want a different order, consider using {@link ImmutableSortedMap} to
401   * sort by keys, or call {@link #orderEntriesByValue(Comparator)}, which changes this builder to
402   * sort entries by value.
403   *
404   * <p>Builder instances can be reused - it is safe to call {@link #buildOrThrow} multiple times to
405   * build multiple maps in series. Each map is a superset of the maps created before it.
406   *
407   * @since 2.0
408   */
409  @DoNotMock
410  public static class Builder<K, V> {
411    @CheckForNull Comparator<? super V> valueComparator;
412    @Nullable Entry<K, V>[] entries;
413    int size;
414    boolean entriesUsed;
415
416    /**
417     * Creates a new builder. The returned builder is equivalent to the builder generated by {@link
418     * ImmutableMap#builder}.
419     */
420    public Builder() {
421      this(ImmutableCollection.Builder.DEFAULT_INITIAL_CAPACITY);
422    }
423
424    @SuppressWarnings({"unchecked", "rawtypes"})
425    Builder(int initialCapacity) {
426      this.entries = new @Nullable Entry[initialCapacity];
427      this.size = 0;
428      this.entriesUsed = false;
429    }
430
431    private void ensureCapacity(int minCapacity) {
432      if (minCapacity > entries.length) {
433        entries =
434            Arrays.copyOf(
435                entries, ImmutableCollection.Builder.expandedCapacity(entries.length, minCapacity));
436        entriesUsed = false;
437      }
438    }
439
440    /**
441     * Associates {@code key} with {@code value} in the built map. Duplicate keys are not allowed,
442     * and will cause {@link #build} to fail.
443     */
444    @CanIgnoreReturnValue
445    public Builder<K, V> put(K key, V value) {
446      ensureCapacity(size + 1);
447      Entry<K, V> entry = entryOf(key, value);
448      // don't inline this: we want to fail atomically if key or value is null
449      entries[size++] = entry;
450      return this;
451    }
452
453    /**
454     * Adds the given {@code entry} to the map, making it immutable if necessary. Duplicate keys are
455     * not allowed, and will cause {@link #build} to fail.
456     *
457     * @since 11.0
458     */
459    @CanIgnoreReturnValue
460    public Builder<K, V> put(Entry<? extends K, ? extends V> entry) {
461      return put(entry.getKey(), entry.getValue());
462    }
463
464    /**
465     * Associates all of the given map's keys and values in the built map. Duplicate keys are not
466     * allowed, and will cause {@link #build} to fail.
467     *
468     * @throws NullPointerException if any key or value in {@code map} is null
469     */
470    @CanIgnoreReturnValue
471    public Builder<K, V> putAll(Map<? extends K, ? extends V> map) {
472      return putAll(map.entrySet());
473    }
474
475    /**
476     * Adds all of the given entries to the built map. Duplicate keys are not allowed, and will
477     * cause {@link #build} to fail.
478     *
479     * @throws NullPointerException if any key, value, or entry is null
480     * @since 19.0
481     */
482    @CanIgnoreReturnValue
483    @Beta
484    public Builder<K, V> putAll(Iterable<? extends Entry<? extends K, ? extends V>> entries) {
485      if (entries instanceof Collection) {
486        ensureCapacity(size + ((Collection<?>) entries).size());
487      }
488      for (Entry<? extends K, ? extends V> entry : entries) {
489        put(entry);
490      }
491      return this;
492    }
493
494    /**
495     * Configures this {@code Builder} to order entries by value according to the specified
496     * comparator.
497     *
498     * <p>The sort order is stable, that is, if two entries have values that compare as equivalent,
499     * the entry that was inserted first will be first in the built map's iteration order.
500     *
501     * @throws IllegalStateException if this method was already called
502     * @since 19.0
503     */
504    @CanIgnoreReturnValue
505    @Beta
506    public Builder<K, V> orderEntriesByValue(Comparator<? super V> valueComparator) {
507      checkState(this.valueComparator == null, "valueComparator was already set");
508      this.valueComparator = checkNotNull(valueComparator, "valueComparator");
509      return this;
510    }
511
512    @CanIgnoreReturnValue
513    Builder<K, V> combine(Builder<K, V> other) {
514      checkNotNull(other);
515      ensureCapacity(this.size + other.size);
516      System.arraycopy(other.entries, 0, this.entries, this.size, other.size);
517      this.size += other.size;
518      return this;
519    }
520
521    /*
522     * TODO(kevinb): Should build() and the ImmutableBiMap & ImmutableSortedMap
523     * versions throw an IllegalStateException instead?
524     */
525
526    /**
527     * Returns a newly-created immutable map. The iteration order of the returned map is the order
528     * in which entries were inserted into the builder, unless {@link #orderEntriesByValue} was
529     * called, in which case entries are sorted by value.
530     *
531     * <p>Prefer the equivalent method {@link #buildOrThrow()} to make it explicit that the method
532     * will throw an exception if there are duplicate keys. The {@code build()} method will soon be
533     * deprecated.
534     *
535     * @throws IllegalArgumentException if duplicate keys were added
536     */
537    public ImmutableMap<K, V> build() {
538      return buildOrThrow();
539    }
540
541    /**
542     * Returns a newly-created immutable map, or throws an exception if any key was added more than
543     * once. The iteration order of the returned map is the order in which entries were inserted
544     * into the builder, unless {@link #orderEntriesByValue} was called, in which case entries are
545     * sorted by value.
546     *
547     * @throws IllegalArgumentException if duplicate keys were added
548     * @since 31.0
549     */
550    public ImmutableMap<K, V> buildOrThrow() {
551      /*
552       * If entries is full, or if hash flooding is detected, then this implementation may end up
553       * using the entries array directly and writing over the entry objects with non-terminal
554       * entries, but this is safe; if this Builder is used further, it will grow the entries array
555       * (so it can't affect the original array), and future build() calls will always copy any
556       * entry objects that cannot be safely reused.
557       */
558      if (valueComparator != null) {
559        if (entriesUsed) {
560          entries = Arrays.copyOf(entries, size);
561        }
562        Arrays.sort(
563            entries, 0, size, Ordering.from(valueComparator).onResultOf(Maps.<V>valueFunction()));
564      }
565      switch (size) {
566        case 0:
567          return of();
568        case 1:
569          // requireNonNull is safe because the first `size` elements have been filled in.
570          Entry<K, V> onlyEntry = requireNonNull(entries[0]);
571          return of(onlyEntry.getKey(), onlyEntry.getValue());
572        default:
573          entriesUsed = true;
574          return RegularImmutableMap.fromEntryArray(size, entries);
575      }
576    }
577
578    @VisibleForTesting // only for testing JDK backed implementation
579    ImmutableMap<K, V> buildJdkBacked() {
580      checkState(
581          valueComparator == null, "buildJdkBacked is only for testing; can't use valueComparator");
582      switch (size) {
583        case 0:
584          return of();
585        case 1:
586          // requireNonNull is safe because the first `size` elements have been filled in.
587          Entry<K, V> onlyEntry = requireNonNull(entries[0]);
588          return of(onlyEntry.getKey(), onlyEntry.getValue());
589        default:
590          entriesUsed = true;
591          return JdkBackedImmutableMap.create(size, entries);
592      }
593    }
594  }
595
596  /**
597   * Returns an immutable map containing the same entries as {@code map}. The returned map iterates
598   * over entries in the same order as the {@code entrySet} of the original map. If {@code map}
599   * somehow contains entries with duplicate keys (for example, if it is a {@code SortedMap} whose
600   * comparator is not <i>consistent with equals</i>), the results of this method are undefined.
601   *
602   * <p>Despite the method name, this method attempts to avoid actually copying the data when it is
603   * safe to do so. The exact circumstances under which a copy will or will not be performed are
604   * undocumented and subject to change.
605   *
606   * @throws NullPointerException if any key or value in {@code map} is null
607   */
608  public static <K, V> ImmutableMap<K, V> copyOf(Map<? extends K, ? extends V> map) {
609    if ((map instanceof ImmutableMap) && !(map instanceof SortedMap)) {
610      @SuppressWarnings("unchecked") // safe since map is not writable
611      ImmutableMap<K, V> kvMap = (ImmutableMap<K, V>) map;
612      if (!kvMap.isPartialView()) {
613        return kvMap;
614      }
615    } else if (map instanceof EnumMap) {
616      @SuppressWarnings("unchecked") // safe since map is not writable
617      ImmutableMap<K, V> kvMap = (ImmutableMap<K, V>) copyOfEnumMap((EnumMap<?, ?>) map);
618      return kvMap;
619    }
620    return copyOf(map.entrySet());
621  }
622
623  /**
624   * Returns an immutable map containing the specified entries. The returned map iterates over
625   * entries in the same order as the original iterable.
626   *
627   * @throws NullPointerException if any key, value, or entry is null
628   * @throws IllegalArgumentException if two entries have the same key
629   * @since 19.0
630   */
631  @Beta
632  public static <K, V> ImmutableMap<K, V> copyOf(
633      Iterable<? extends Entry<? extends K, ? extends V>> entries) {
634    @SuppressWarnings("unchecked") // we'll only be using getKey and getValue, which are covariant
635    Entry<K, V>[] entryArray = (Entry<K, V>[]) Iterables.toArray(entries, EMPTY_ENTRY_ARRAY);
636    switch (entryArray.length) {
637      case 0:
638        return of();
639      case 1:
640        // requireNonNull is safe because the first `size` elements have been filled in.
641        Entry<K, V> onlyEntry = requireNonNull(entryArray[0]);
642        return of(onlyEntry.getKey(), onlyEntry.getValue());
643      default:
644        /*
645         * The current implementation will end up using entryArray directly, though it will write
646         * over the (arbitrary, potentially mutable) Entry objects actually stored in entryArray.
647         */
648        return RegularImmutableMap.fromEntries(entryArray);
649    }
650  }
651
652  private static <K extends Enum<K>, V> ImmutableMap<K, V> copyOfEnumMap(
653      EnumMap<K, ? extends V> original) {
654    EnumMap<K, V> copy = new EnumMap<>(original);
655    for (Entry<K, V> entry : copy.entrySet()) {
656      checkEntryNotNull(entry.getKey(), entry.getValue());
657    }
658    return ImmutableEnumMap.asImmutable(copy);
659  }
660
661  static final Entry<?, ?>[] EMPTY_ENTRY_ARRAY = new Entry<?, ?>[0];
662
663  abstract static class IteratorBasedImmutableMap<K, V> extends ImmutableMap<K, V> {
664    abstract UnmodifiableIterator<Entry<K, V>> entryIterator();
665
666    Spliterator<Entry<K, V>> entrySpliterator() {
667      return Spliterators.spliterator(
668          entryIterator(),
669          size(),
670          Spliterator.DISTINCT | Spliterator.NONNULL | Spliterator.IMMUTABLE | Spliterator.ORDERED);
671    }
672
673    @Override
674    ImmutableSet<K> createKeySet() {
675      return new ImmutableMapKeySet<>(this);
676    }
677
678    @Override
679    ImmutableSet<Entry<K, V>> createEntrySet() {
680      class EntrySetImpl extends ImmutableMapEntrySet<K, V> {
681        @Override
682        ImmutableMap<K, V> map() {
683          return IteratorBasedImmutableMap.this;
684        }
685
686        @Override
687        public UnmodifiableIterator<Entry<K, V>> iterator() {
688          return entryIterator();
689        }
690      }
691      return new EntrySetImpl();
692    }
693
694    @Override
695    ImmutableCollection<V> createValues() {
696      return new ImmutableMapValues<>(this);
697    }
698  }
699
700  ImmutableMap() {}
701
702  /**
703   * Guaranteed to throw an exception and leave the map unmodified.
704   *
705   * @throws UnsupportedOperationException always
706   * @deprecated Unsupported operation.
707   */
708  @CanIgnoreReturnValue
709  @Deprecated
710  @Override
711  @DoNotCall("Always throws UnsupportedOperationException")
712  @CheckForNull
713  public final V put(K k, V v) {
714    throw new UnsupportedOperationException();
715  }
716
717  /**
718   * Guaranteed to throw an exception and leave the map unmodified.
719   *
720   * @throws UnsupportedOperationException always
721   * @deprecated Unsupported operation.
722   */
723  @CanIgnoreReturnValue
724  @Deprecated
725  @Override
726  @DoNotCall("Always throws UnsupportedOperationException")
727  @CheckForNull
728  public final V putIfAbsent(K key, V value) {
729    throw new UnsupportedOperationException();
730  }
731
732  /**
733   * Guaranteed to throw an exception and leave the map unmodified.
734   *
735   * @throws UnsupportedOperationException always
736   * @deprecated Unsupported operation.
737   */
738  @Deprecated
739  @Override
740  @DoNotCall("Always throws UnsupportedOperationException")
741  public final boolean replace(K key, V oldValue, V newValue) {
742    throw new UnsupportedOperationException();
743  }
744
745  /**
746   * Guaranteed to throw an exception and leave the map unmodified.
747   *
748   * @throws UnsupportedOperationException always
749   * @deprecated Unsupported operation.
750   */
751  @Deprecated
752  @Override
753  @CheckForNull
754  @DoNotCall("Always throws UnsupportedOperationException")
755  public final V replace(K key, V value) {
756    throw new UnsupportedOperationException();
757  }
758
759  /**
760   * Guaranteed to throw an exception and leave the map unmodified.
761   *
762   * @throws UnsupportedOperationException always
763   * @deprecated Unsupported operation.
764   */
765  @Deprecated
766  @Override
767  @DoNotCall("Always throws UnsupportedOperationException")
768  public final V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
769    throw new UnsupportedOperationException();
770  }
771
772  /**
773   * Guaranteed to throw an exception and leave the map unmodified.
774   *
775   * @throws UnsupportedOperationException always
776   * @deprecated Unsupported operation.
777   */
778  @Deprecated
779  @Override
780  @DoNotCall("Always throws UnsupportedOperationException")
781  public final V computeIfPresent(
782      K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
783    throw new UnsupportedOperationException();
784  }
785
786  /**
787   * Guaranteed to throw an exception and leave the map unmodified.
788   *
789   * @throws UnsupportedOperationException always
790   * @deprecated Unsupported operation.
791   */
792  @Deprecated
793  @Override
794  @DoNotCall("Always throws UnsupportedOperationException")
795  public final V compute(
796      K key, BiFunction<? super K, ? super @Nullable V, ? extends V> remappingFunction) {
797    throw new UnsupportedOperationException();
798  }
799
800  /**
801   * Guaranteed to throw an exception and leave the map unmodified.
802   *
803   * @throws UnsupportedOperationException always
804   * @deprecated Unsupported operation.
805   */
806  @Deprecated
807  @Override
808  @DoNotCall("Always throws UnsupportedOperationException")
809  public final V merge(
810      K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
811    throw new UnsupportedOperationException();
812  }
813
814  /**
815   * Guaranteed to throw an exception and leave the map unmodified.
816   *
817   * @throws UnsupportedOperationException always
818   * @deprecated Unsupported operation.
819   */
820  @Deprecated
821  @Override
822  @DoNotCall("Always throws UnsupportedOperationException")
823  public final void putAll(Map<? extends K, ? extends V> map) {
824    throw new UnsupportedOperationException();
825  }
826
827  /**
828   * Guaranteed to throw an exception and leave the map unmodified.
829   *
830   * @throws UnsupportedOperationException always
831   * @deprecated Unsupported operation.
832   */
833  @Deprecated
834  @Override
835  @DoNotCall("Always throws UnsupportedOperationException")
836  public final void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
837    throw new UnsupportedOperationException();
838  }
839
840  /**
841   * Guaranteed to throw an exception and leave the map unmodified.
842   *
843   * @throws UnsupportedOperationException always
844   * @deprecated Unsupported operation.
845   */
846  @Deprecated
847  @Override
848  @DoNotCall("Always throws UnsupportedOperationException")
849  @CheckForNull
850  public final V remove(@CheckForNull Object o) {
851    throw new UnsupportedOperationException();
852  }
853
854  /**
855   * Guaranteed to throw an exception and leave the map unmodified.
856   *
857   * @throws UnsupportedOperationException always
858   * @deprecated Unsupported operation.
859   */
860  @Deprecated
861  @Override
862  @DoNotCall("Always throws UnsupportedOperationException")
863  public final boolean remove(@CheckForNull Object key, @CheckForNull Object value) {
864    throw new UnsupportedOperationException();
865  }
866
867  /**
868   * Guaranteed to throw an exception and leave the map unmodified.
869   *
870   * @throws UnsupportedOperationException always
871   * @deprecated Unsupported operation.
872   */
873  @Deprecated
874  @Override
875  @DoNotCall("Always throws UnsupportedOperationException")
876  public final void clear() {
877    throw new UnsupportedOperationException();
878  }
879
880  @Override
881  public boolean isEmpty() {
882    return size() == 0;
883  }
884
885  @Override
886  public boolean containsKey(@CheckForNull Object key) {
887    return get(key) != null;
888  }
889
890  @Override
891  public boolean containsValue(@CheckForNull Object value) {
892    return values().contains(value);
893  }
894
895  // Overriding to mark it Nullable
896  @Override
897  @CheckForNull
898  public abstract V get(@CheckForNull Object key);
899
900  /**
901   * @since 21.0 (but only since 23.5 in the Android <a
902   *     href="https://github.com/google/guava#guava-google-core-libraries-for-java">flavor</a>).
903   *     Note, however, that Java 8 users can call this method with any version and flavor of Guava.
904   */
905  @Override
906  @CheckForNull
907  public final V getOrDefault(@CheckForNull Object key, @CheckForNull V defaultValue) {
908    V result = get(key);
909    // TODO(b/192579700): Use a ternary once it no longer confuses our nullness checker.
910    if (result != null) {
911      return result;
912    } else {
913      return defaultValue;
914    }
915  }
916
917  @LazyInit @RetainedWith @CheckForNull private transient ImmutableSet<Entry<K, V>> entrySet;
918
919  /**
920   * Returns an immutable set of the mappings in this map. The iteration order is specified by the
921   * method used to create this map. Typically, this is insertion order.
922   */
923  @Override
924  public ImmutableSet<Entry<K, V>> entrySet() {
925    ImmutableSet<Entry<K, V>> result = entrySet;
926    return (result == null) ? entrySet = createEntrySet() : result;
927  }
928
929  abstract ImmutableSet<Entry<K, V>> createEntrySet();
930
931  @LazyInit @RetainedWith @CheckForNull private transient ImmutableSet<K> keySet;
932
933  /**
934   * Returns an immutable set of the keys in this map, in the same order that they appear in {@link
935   * #entrySet}.
936   */
937  @Override
938  public ImmutableSet<K> keySet() {
939    ImmutableSet<K> result = keySet;
940    return (result == null) ? keySet = createKeySet() : result;
941  }
942
943  /*
944   * This could have a good default implementation of return new ImmutableKeySet<K, V>(this),
945   * but ProGuard can't figure out how to eliminate that default when RegularImmutableMap
946   * overrides it.
947   */
948  abstract ImmutableSet<K> createKeySet();
949
950  UnmodifiableIterator<K> keyIterator() {
951    final UnmodifiableIterator<Entry<K, V>> entryIterator = entrySet().iterator();
952    return new UnmodifiableIterator<K>() {
953      @Override
954      public boolean hasNext() {
955        return entryIterator.hasNext();
956      }
957
958      @Override
959      public K next() {
960        return entryIterator.next().getKey();
961      }
962    };
963  }
964
965  Spliterator<K> keySpliterator() {
966    return CollectSpliterators.map(entrySet().spliterator(), Entry::getKey);
967  }
968
969  @LazyInit @RetainedWith @CheckForNull private transient ImmutableCollection<V> values;
970
971  /**
972   * Returns an immutable collection of the values in this map, in the same order that they appear
973   * in {@link #entrySet}.
974   */
975  @Override
976  public ImmutableCollection<V> values() {
977    ImmutableCollection<V> result = values;
978    return (result == null) ? values = createValues() : result;
979  }
980
981  /*
982   * This could have a good default implementation of {@code return new
983   * ImmutableMapValues<K, V>(this)}, but ProGuard can't figure out how to eliminate that default
984   * when RegularImmutableMap overrides it.
985   */
986  abstract ImmutableCollection<V> createValues();
987
988  // cached so that this.multimapView().inverse() only computes inverse once
989  @LazyInit @CheckForNull private transient ImmutableSetMultimap<K, V> multimapView;
990
991  /**
992   * Returns a multimap view of the map.
993   *
994   * @since 14.0
995   */
996  public ImmutableSetMultimap<K, V> asMultimap() {
997    if (isEmpty()) {
998      return ImmutableSetMultimap.of();
999    }
1000    ImmutableSetMultimap<K, V> result = multimapView;
1001    return (result == null)
1002        ? (multimapView =
1003            new ImmutableSetMultimap<>(new MapViewOfValuesAsSingletonSets(), size(), null))
1004        : result;
1005  }
1006
1007  @WeakOuter
1008  private final class MapViewOfValuesAsSingletonSets
1009      extends IteratorBasedImmutableMap<K, ImmutableSet<V>> {
1010
1011    @Override
1012    public int size() {
1013      return ImmutableMap.this.size();
1014    }
1015
1016    @Override
1017    ImmutableSet<K> createKeySet() {
1018      return ImmutableMap.this.keySet();
1019    }
1020
1021    @Override
1022    public boolean containsKey(@CheckForNull Object key) {
1023      return ImmutableMap.this.containsKey(key);
1024    }
1025
1026    @Override
1027    @CheckForNull
1028    public ImmutableSet<V> get(@CheckForNull Object key) {
1029      V outerValue = ImmutableMap.this.get(key);
1030      return (outerValue == null) ? null : ImmutableSet.of(outerValue);
1031    }
1032
1033    @Override
1034    boolean isPartialView() {
1035      return ImmutableMap.this.isPartialView();
1036    }
1037
1038    @Override
1039    public int hashCode() {
1040      // ImmutableSet.of(value).hashCode() == value.hashCode(), so the hashes are the same
1041      return ImmutableMap.this.hashCode();
1042    }
1043
1044    @Override
1045    boolean isHashCodeFast() {
1046      return ImmutableMap.this.isHashCodeFast();
1047    }
1048
1049    @Override
1050    UnmodifiableIterator<Entry<K, ImmutableSet<V>>> entryIterator() {
1051      final Iterator<Entry<K, V>> backingIterator = ImmutableMap.this.entrySet().iterator();
1052      return new UnmodifiableIterator<Entry<K, ImmutableSet<V>>>() {
1053        @Override
1054        public boolean hasNext() {
1055          return backingIterator.hasNext();
1056        }
1057
1058        @Override
1059        public Entry<K, ImmutableSet<V>> next() {
1060          final Entry<K, V> backingEntry = backingIterator.next();
1061          return new AbstractMapEntry<K, ImmutableSet<V>>() {
1062            @Override
1063            public K getKey() {
1064              return backingEntry.getKey();
1065            }
1066
1067            @Override
1068            public ImmutableSet<V> getValue() {
1069              return ImmutableSet.of(backingEntry.getValue());
1070            }
1071          };
1072        }
1073      };
1074    }
1075  }
1076
1077  @Override
1078  public boolean equals(@CheckForNull Object object) {
1079    return Maps.equalsImpl(this, object);
1080  }
1081
1082  abstract boolean isPartialView();
1083
1084  @Override
1085  public int hashCode() {
1086    return Sets.hashCodeImpl(entrySet());
1087  }
1088
1089  boolean isHashCodeFast() {
1090    return false;
1091  }
1092
1093  @Override
1094  public String toString() {
1095    return Maps.toStringImpl(this);
1096  }
1097
1098  /**
1099   * Serialized type for all ImmutableMap instances. It captures the logical contents and they are
1100   * reconstructed using public factory methods. This ensures that the implementation types remain
1101   * as implementation details.
1102   */
1103  static class SerializedForm<K, V> implements Serializable {
1104    // This object retains references to collections returned by keySet() and value(). This saves
1105    // bytes when the both the map and its keySet or value collection are written to the same
1106    // instance of ObjectOutputStream.
1107
1108    // TODO(b/160980469): remove support for the old serialization format after some time
1109    private static final boolean USE_LEGACY_SERIALIZATION = true;
1110
1111    private final Object keys;
1112    private final Object values;
1113
1114    SerializedForm(ImmutableMap<K, V> map) {
1115      if (USE_LEGACY_SERIALIZATION) {
1116        Object[] keys = new Object[map.size()];
1117        Object[] values = new Object[map.size()];
1118        int i = 0;
1119        // "extends Object" works around https://github.com/typetools/checker-framework/issues/3013
1120        for (Entry<? extends Object, ? extends Object> entry : map.entrySet()) {
1121          keys[i] = entry.getKey();
1122          values[i] = entry.getValue();
1123          i++;
1124        }
1125        this.keys = keys;
1126        this.values = values;
1127        return;
1128      }
1129      this.keys = map.keySet();
1130      this.values = map.values();
1131    }
1132
1133    @SuppressWarnings("unchecked")
1134    final Object readResolve() {
1135      if (!(this.keys instanceof ImmutableSet)) {
1136        return legacyReadResolve();
1137      }
1138
1139      ImmutableSet<K> keySet = (ImmutableSet<K>) this.keys;
1140      ImmutableCollection<V> values = (ImmutableCollection<V>) this.values;
1141
1142      Builder<K, V> builder = makeBuilder(keySet.size());
1143
1144      UnmodifiableIterator<K> keyIter = keySet.iterator();
1145      UnmodifiableIterator<V> valueIter = values.iterator();
1146
1147      while (keyIter.hasNext()) {
1148        builder.put(keyIter.next(), valueIter.next());
1149      }
1150
1151      return builder.build();
1152    }
1153
1154    @SuppressWarnings("unchecked")
1155    final Object legacyReadResolve() {
1156      K[] keys = (K[]) this.keys;
1157      V[] values = (V[]) this.values;
1158
1159      Builder<K, V> builder = makeBuilder(keys.length);
1160
1161      for (int i = 0; i < keys.length; i++) {
1162        builder.put(keys[i], values[i]);
1163      }
1164      return builder.build();
1165    }
1166
1167    /**
1168     * Returns a builder that builds the unserialized type. Subclasses should override this method.
1169     */
1170    Builder<K, V> makeBuilder(int size) {
1171      return new Builder<>(size);
1172    }
1173
1174    private static final long serialVersionUID = 0;
1175  }
1176
1177  /**
1178   * Returns a serializable form of this object. Non-public subclasses should not override this
1179   * method. Publicly-accessible subclasses must override this method and should return a subclass
1180   * of SerializedForm whose readResolve() method returns objects of the subclass type.
1181   */
1182  Object writeReplace() {
1183    return new SerializedForm<>(this);
1184  }
1185}