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