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  @CheckForNull
877  public final V merge(
878      K key, V value, BiFunction<? super V, ? super V, ? extends @Nullable V> function) {
879    throw new UnsupportedOperationException();
880  }
881
882  /**
883   * Guaranteed to throw an exception and leave the map unmodified.
884   *
885   * @throws UnsupportedOperationException always
886   * @deprecated Unsupported operation.
887   */
888  @Deprecated
889  @Override
890  @DoNotCall("Always throws UnsupportedOperationException")
891  public final void putAll(Map<? extends K, ? extends V> map) {
892    throw new UnsupportedOperationException();
893  }
894
895  /**
896   * Guaranteed to throw an exception and leave the map unmodified.
897   *
898   * @throws UnsupportedOperationException always
899   * @deprecated Unsupported operation.
900   */
901  @Deprecated
902  @Override
903  @DoNotCall("Always throws UnsupportedOperationException")
904  public final void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
905    throw new UnsupportedOperationException();
906  }
907
908  /**
909   * Guaranteed to throw an exception and leave the map unmodified.
910   *
911   * @throws UnsupportedOperationException always
912   * @deprecated Unsupported operation.
913   */
914  @Deprecated
915  @Override
916  @DoNotCall("Always throws UnsupportedOperationException")
917  @CheckForNull
918  public final V remove(@CheckForNull Object o) {
919    throw new UnsupportedOperationException();
920  }
921
922  /**
923   * Guaranteed to throw an exception and leave the map unmodified.
924   *
925   * @throws UnsupportedOperationException always
926   * @deprecated Unsupported operation.
927   */
928  @Deprecated
929  @Override
930  @DoNotCall("Always throws UnsupportedOperationException")
931  public final boolean remove(@CheckForNull Object key, @CheckForNull Object value) {
932    throw new UnsupportedOperationException();
933  }
934
935  /**
936   * Guaranteed to throw an exception and leave the map unmodified.
937   *
938   * @throws UnsupportedOperationException always
939   * @deprecated Unsupported operation.
940   */
941  @Deprecated
942  @Override
943  @DoNotCall("Always throws UnsupportedOperationException")
944  public final void clear() {
945    throw new UnsupportedOperationException();
946  }
947
948  @Override
949  public boolean isEmpty() {
950    return size() == 0;
951  }
952
953  @Override
954  public boolean containsKey(@CheckForNull Object key) {
955    return get(key) != null;
956  }
957
958  @Override
959  public boolean containsValue(@CheckForNull Object value) {
960    return values().contains(value);
961  }
962
963  // Overriding to mark it Nullable
964  @Override
965  @CheckForNull
966  public abstract V get(@CheckForNull Object key);
967
968  /**
969   * @since 21.0 (but only since 23.5 in the Android <a
970   *     href="https://github.com/google/guava#guava-google-core-libraries-for-java">flavor</a>).
971   *     Note, however, that Java 8 users can call this method with any version and flavor of Guava.
972   */
973  @Override
974  @CheckForNull
975  public final V getOrDefault(@CheckForNull Object key, @CheckForNull V defaultValue) {
976    /*
977     * Even though it's weird to pass a defaultValue that is null, some callers do so. Those who
978     * pass a literal "null" should probably just use `get`, but I would expect other callers to
979     * pass an expression that *might* be null. This could happen with:
980     *
981     * - a `getFooOrDefault(@CheckForNull Foo defaultValue)` method that returns
982     *   `map.getOrDefault(FOO_KEY, defaultValue)`
983     *
984     * - a call that consults a chain of maps, as in `mapA.getOrDefault(key, mapB.getOrDefault(key,
985     *   ...))`
986     *
987     * So it makes sense for the parameter (and thus the return type) to be @CheckForNull.
988     *
989     * Two other points:
990     *
991     * 1. We'll want to use something like @PolyNull once we can make that work for the various
992     * platforms we target.
993     *
994     * 2. Kotlin's Map type has a getOrDefault method that accepts and returns a "plain V," in
995     * contrast to the "V?" type that we're using. As a result, Kotlin sees a conflict between the
996     * nullness annotations in ImmutableMap and those in its own Map type. In response, it considers
997     * the parameter and return type both to be platform types. As a result, Kotlin permits calls
998     * that can lead to NullPointerException. That's unfortunate. But hopefully most Kotlin callers
999     * use `get(key) ?: defaultValue` instead of this method, anyway.
1000     */
1001    V result = get(key);
1002    // TODO(b/192579700): Use a ternary once it no longer confuses our nullness checker.
1003    if (result != null) {
1004      return result;
1005    } else {
1006      return defaultValue;
1007    }
1008  }
1009
1010  @LazyInit @RetainedWith @CheckForNull private transient ImmutableSet<Entry<K, V>> entrySet;
1011
1012  /**
1013   * Returns an immutable set of the mappings in this map. The iteration order is specified by the
1014   * method used to create this map. Typically, this is insertion order.
1015   */
1016  @Override
1017  public ImmutableSet<Entry<K, V>> entrySet() {
1018    ImmutableSet<Entry<K, V>> result = entrySet;
1019    return (result == null) ? entrySet = createEntrySet() : result;
1020  }
1021
1022  abstract ImmutableSet<Entry<K, V>> createEntrySet();
1023
1024  @LazyInit @RetainedWith @CheckForNull private transient ImmutableSet<K> keySet;
1025
1026  /**
1027   * Returns an immutable set of the keys in this map, in the same order that they appear in {@link
1028   * #entrySet}.
1029   */
1030  @Override
1031  public ImmutableSet<K> keySet() {
1032    ImmutableSet<K> result = keySet;
1033    return (result == null) ? keySet = createKeySet() : result;
1034  }
1035
1036  /*
1037   * This could have a good default implementation of return new ImmutableKeySet<K, V>(this),
1038   * but ProGuard can't figure out how to eliminate that default when RegularImmutableMap
1039   * overrides it.
1040   */
1041  abstract ImmutableSet<K> createKeySet();
1042
1043  UnmodifiableIterator<K> keyIterator() {
1044    final UnmodifiableIterator<Entry<K, V>> entryIterator = entrySet().iterator();
1045    return new UnmodifiableIterator<K>() {
1046      @Override
1047      public boolean hasNext() {
1048        return entryIterator.hasNext();
1049      }
1050
1051      @Override
1052      public K next() {
1053        return entryIterator.next().getKey();
1054      }
1055    };
1056  }
1057
1058  Spliterator<K> keySpliterator() {
1059    return CollectSpliterators.map(entrySet().spliterator(), Entry::getKey);
1060  }
1061
1062  @LazyInit @RetainedWith @CheckForNull private transient ImmutableCollection<V> values;
1063
1064  /**
1065   * Returns an immutable collection of the values in this map, in the same order that they appear
1066   * in {@link #entrySet}.
1067   */
1068  @Override
1069  public ImmutableCollection<V> values() {
1070    ImmutableCollection<V> result = values;
1071    return (result == null) ? values = createValues() : result;
1072  }
1073
1074  /*
1075   * This could have a good default implementation of {@code return new
1076   * ImmutableMapValues<K, V>(this)}, but ProGuard can't figure out how to eliminate that default
1077   * when RegularImmutableMap overrides it.
1078   */
1079  abstract ImmutableCollection<V> createValues();
1080
1081  // cached so that this.multimapView().inverse() only computes inverse once
1082  @LazyInit @CheckForNull private transient ImmutableSetMultimap<K, V> multimapView;
1083
1084  /**
1085   * Returns a multimap view of the map.
1086   *
1087   * @since 14.0
1088   */
1089  public ImmutableSetMultimap<K, V> asMultimap() {
1090    if (isEmpty()) {
1091      return ImmutableSetMultimap.of();
1092    }
1093    ImmutableSetMultimap<K, V> result = multimapView;
1094    return (result == null)
1095        ? (multimapView =
1096            new ImmutableSetMultimap<>(new MapViewOfValuesAsSingletonSets(), size(), null))
1097        : result;
1098  }
1099
1100  @WeakOuter
1101  private final class MapViewOfValuesAsSingletonSets
1102      extends IteratorBasedImmutableMap<K, ImmutableSet<V>> {
1103
1104    @Override
1105    public int size() {
1106      return ImmutableMap.this.size();
1107    }
1108
1109    @Override
1110    ImmutableSet<K> createKeySet() {
1111      return ImmutableMap.this.keySet();
1112    }
1113
1114    @Override
1115    public boolean containsKey(@CheckForNull Object key) {
1116      return ImmutableMap.this.containsKey(key);
1117    }
1118
1119    @Override
1120    @CheckForNull
1121    public ImmutableSet<V> get(@CheckForNull Object key) {
1122      V outerValue = ImmutableMap.this.get(key);
1123      return (outerValue == null) ? null : ImmutableSet.of(outerValue);
1124    }
1125
1126    @Override
1127    boolean isPartialView() {
1128      return ImmutableMap.this.isPartialView();
1129    }
1130
1131    @Override
1132    public int hashCode() {
1133      // ImmutableSet.of(value).hashCode() == value.hashCode(), so the hashes are the same
1134      return ImmutableMap.this.hashCode();
1135    }
1136
1137    @Override
1138    boolean isHashCodeFast() {
1139      return ImmutableMap.this.isHashCodeFast();
1140    }
1141
1142    @Override
1143    UnmodifiableIterator<Entry<K, ImmutableSet<V>>> entryIterator() {
1144      final Iterator<Entry<K, V>> backingIterator = ImmutableMap.this.entrySet().iterator();
1145      return new UnmodifiableIterator<Entry<K, ImmutableSet<V>>>() {
1146        @Override
1147        public boolean hasNext() {
1148          return backingIterator.hasNext();
1149        }
1150
1151        @Override
1152        public Entry<K, ImmutableSet<V>> next() {
1153          final Entry<K, V> backingEntry = backingIterator.next();
1154          return new AbstractMapEntry<K, ImmutableSet<V>>() {
1155            @Override
1156            public K getKey() {
1157              return backingEntry.getKey();
1158            }
1159
1160            @Override
1161            public ImmutableSet<V> getValue() {
1162              return ImmutableSet.of(backingEntry.getValue());
1163            }
1164          };
1165        }
1166      };
1167    }
1168  }
1169
1170  @Override
1171  public boolean equals(@CheckForNull Object object) {
1172    return Maps.equalsImpl(this, object);
1173  }
1174
1175  abstract boolean isPartialView();
1176
1177  @Override
1178  public int hashCode() {
1179    return Sets.hashCodeImpl(entrySet());
1180  }
1181
1182  boolean isHashCodeFast() {
1183    return false;
1184  }
1185
1186  @Override
1187  public String toString() {
1188    return Maps.toStringImpl(this);
1189  }
1190
1191  /**
1192   * Serialized type for all ImmutableMap instances. It captures the logical contents and they are
1193   * reconstructed using public factory methods. This ensures that the implementation types remain
1194   * as implementation details.
1195   */
1196  @J2ktIncompatible // serialization
1197  static class SerializedForm<K, V> implements Serializable {
1198    // This object retains references to collections returned by keySet() and value(). This saves
1199    // bytes when the both the map and its keySet or value collection are written to the same
1200    // instance of ObjectOutputStream.
1201
1202    // TODO(b/160980469): remove support for the old serialization format after some time
1203    private static final boolean USE_LEGACY_SERIALIZATION = true;
1204
1205    private final Object keys;
1206    private final Object values;
1207
1208    SerializedForm(ImmutableMap<K, V> map) {
1209      if (USE_LEGACY_SERIALIZATION) {
1210        Object[] keys = new Object[map.size()];
1211        Object[] values = new Object[map.size()];
1212        int i = 0;
1213        // "extends Object" works around https://github.com/typetools/checker-framework/issues/3013
1214        for (Entry<? extends Object, ? extends Object> entry : map.entrySet()) {
1215          keys[i] = entry.getKey();
1216          values[i] = entry.getValue();
1217          i++;
1218        }
1219        this.keys = keys;
1220        this.values = values;
1221        return;
1222      }
1223      this.keys = map.keySet();
1224      this.values = map.values();
1225    }
1226
1227    @SuppressWarnings("unchecked")
1228    final Object readResolve() {
1229      if (!(this.keys instanceof ImmutableSet)) {
1230        return legacyReadResolve();
1231      }
1232
1233      ImmutableSet<K> keySet = (ImmutableSet<K>) this.keys;
1234      ImmutableCollection<V> values = (ImmutableCollection<V>) this.values;
1235
1236      Builder<K, V> builder = makeBuilder(keySet.size());
1237
1238      UnmodifiableIterator<K> keyIter = keySet.iterator();
1239      UnmodifiableIterator<V> valueIter = values.iterator();
1240
1241      while (keyIter.hasNext()) {
1242        builder.put(keyIter.next(), valueIter.next());
1243      }
1244
1245      return builder.buildOrThrow();
1246    }
1247
1248    @SuppressWarnings("unchecked")
1249    final Object legacyReadResolve() {
1250      K[] keys = (K[]) this.keys;
1251      V[] values = (V[]) this.values;
1252
1253      Builder<K, V> builder = makeBuilder(keys.length);
1254
1255      for (int i = 0; i < keys.length; i++) {
1256        builder.put(keys[i], values[i]);
1257      }
1258      return builder.buildOrThrow();
1259    }
1260
1261    /**
1262     * Returns a builder that builds the unserialized type. Subclasses should override this method.
1263     */
1264    Builder<K, V> makeBuilder(int size) {
1265      return new Builder<>(size);
1266    }
1267
1268    private static final long serialVersionUID = 0;
1269  }
1270
1271  /**
1272   * Returns a serializable form of this object. Non-public subclasses should not override this
1273   * method. Publicly-accessible subclasses must override this method and should return a subclass
1274   * of SerializedForm whose readResolve() method returns objects of the subclass type.
1275   */
1276  @J2ktIncompatible // serialization
1277  Object writeReplace() {
1278    return new SerializedForm<>(this);
1279  }
1280
1281  @J2ktIncompatible // java.io.ObjectInputStream
1282  private void readObject(ObjectInputStream stream) throws InvalidObjectException {
1283    throw new InvalidObjectException("Use SerializedForm");
1284  }
1285}