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