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