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