001/*
002 * Copyright (C) 2009 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.checkArgument;
020import static com.google.common.base.Preconditions.checkNotNull;
021import static com.google.common.collect.CollectPreconditions.checkEntryNotNull;
022import static com.google.common.collect.Maps.keyOrNull;
023import static java.util.Objects.requireNonNull;
024
025import com.google.common.annotations.Beta;
026import com.google.common.annotations.GwtCompatible;
027import com.google.errorprone.annotations.CanIgnoreReturnValue;
028import com.google.errorprone.annotations.DoNotCall;
029import java.util.AbstractMap;
030import java.util.Arrays;
031import java.util.Comparator;
032import java.util.Map;
033import java.util.NavigableMap;
034import java.util.SortedMap;
035import java.util.TreeMap;
036import javax.annotation.CheckForNull;
037import org.checkerframework.checker.nullness.qual.Nullable;
038
039/**
040 * A {@link NavigableMap} whose contents will never change, with many other important properties
041 * detailed at {@link ImmutableCollection}.
042 *
043 * <p><b>Warning:</b> as with any sorted collection, you are strongly advised not to use a {@link
044 * Comparator} or {@link Comparable} type whose comparison behavior is <i>inconsistent with
045 * equals</i>. That is, {@code a.compareTo(b)} or {@code comparator.compare(a, b)} should equal zero
046 * <i>if and only if</i> {@code a.equals(b)}. If this advice is not followed, the resulting map will
047 * not correctly obey its specification.
048 *
049 * <p>See the Guava User Guide article on <a href=
050 * "https://github.com/google/guava/wiki/ImmutableCollectionsExplained">immutable collections</a>.
051 *
052 * @author Jared Levy
053 * @author Louis Wasserman
054 * @since 2.0 (implements {@code NavigableMap} since 12.0)
055 */
056@GwtCompatible(serializable = true, emulated = true)
057@ElementTypesAreNonnullByDefault
058public final class ImmutableSortedMap<K, V> extends ImmutableSortedMapFauxverideShim<K, V>
059    implements NavigableMap<K, V> {
060
061  /*
062   * TODO(kevinb): Confirm that ImmutableSortedMap is faster to construct and
063   * uses less memory than TreeMap; then say so in the class Javadoc.
064   */
065  private static final Comparator<Comparable> NATURAL_ORDER = Ordering.natural();
066
067  private static final ImmutableSortedMap<Comparable, Object> NATURAL_EMPTY_MAP =
068      new ImmutableSortedMap<>(
069          ImmutableSortedSet.emptySet(Ordering.natural()), ImmutableList.<Object>of());
070
071  static <K, V> ImmutableSortedMap<K, V> emptyMap(Comparator<? super K> comparator) {
072    if (Ordering.natural().equals(comparator)) {
073      return of();
074    } else {
075      return new ImmutableSortedMap<>(
076          ImmutableSortedSet.emptySet(comparator), ImmutableList.<V>of());
077    }
078  }
079
080  /**
081   * Returns the empty sorted map.
082   *
083   * <p><b>Performance note:</b> the instance returned is a singleton.
084   */
085  @SuppressWarnings("unchecked")
086  // unsafe, comparator() returns a comparator on the specified type
087  // TODO(kevinb): evaluate whether or not of().comparator() should return null
088  public static <K, V> ImmutableSortedMap<K, V> of() {
089    return (ImmutableSortedMap<K, V>) NATURAL_EMPTY_MAP;
090  }
091
092  /** Returns an immutable map containing a single entry. */
093  public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V> of(K k1, V v1) {
094    return of(Ordering.natural(), k1, v1);
095  }
096
097  /** Returns an immutable map containing a single entry. */
098  private static <K, V> ImmutableSortedMap<K, V> of(Comparator<? super K> comparator, K k1, V v1) {
099    return new ImmutableSortedMap<>(
100        new RegularImmutableSortedSet<K>(ImmutableList.of(k1), checkNotNull(comparator)),
101        ImmutableList.of(v1));
102  }
103
104  /**
105   * Returns an immutable sorted map containing the given entries, sorted by the natural ordering of
106   * their keys.
107   *
108   * @throws IllegalArgumentException if the two keys are equal according to their natural ordering
109   */
110  @SuppressWarnings("unchecked")
111  public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V> of(
112      K k1, V v1, K k2, V v2) {
113    return fromEntries(entryOf(k1, v1), entryOf(k2, v2));
114  }
115
116  /**
117   * Returns an immutable sorted map containing the given entries, sorted by the natural ordering of
118   * their keys.
119   *
120   * @throws IllegalArgumentException if any two keys are equal according to their natural ordering
121   */
122  @SuppressWarnings("unchecked")
123  public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V> of(
124      K k1, V v1, K k2, V v2, K k3, V v3) {
125    return fromEntries(entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3));
126  }
127
128  /**
129   * Returns an immutable sorted map containing the given entries, sorted by the natural ordering of
130   * their keys.
131   *
132   * @throws IllegalArgumentException if any two keys are equal according to their natural ordering
133   */
134  @SuppressWarnings("unchecked")
135  public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V> of(
136      K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
137    return fromEntries(entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3), entryOf(k4, v4));
138  }
139
140  /**
141   * Returns an immutable sorted map containing the given entries, sorted by the natural ordering of
142   * their keys.
143   *
144   * @throws IllegalArgumentException if any two keys are equal according to their natural ordering
145   */
146  @SuppressWarnings("unchecked")
147  public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V> of(
148      K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
149    return fromEntries(
150        entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3), entryOf(k4, v4), entryOf(k5, v5));
151  }
152
153  /**
154   * Returns an immutable sorted map containing the given entries, sorted by the natural ordering of
155   * their keys.
156   *
157   * @throws IllegalArgumentException if any two keys are equal according to their natural ordering
158   * @since 31.0
159   */
160  @SuppressWarnings("unchecked")
161  public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V> of(
162      K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6) {
163    return fromEntries(
164        entryOf(k1, v1),
165        entryOf(k2, v2),
166        entryOf(k3, v3),
167        entryOf(k4, v4),
168        entryOf(k5, v5),
169        entryOf(k6, v6));
170  }
171
172  /**
173   * Returns an immutable sorted map containing the given entries, sorted by the natural ordering of
174   * their keys.
175   *
176   * @throws IllegalArgumentException if any two keys are equal according to their natural ordering
177   * @since 31.0
178   */
179  @SuppressWarnings("unchecked")
180  public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V> of(
181      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) {
182    return fromEntries(
183        entryOf(k1, v1),
184        entryOf(k2, v2),
185        entryOf(k3, v3),
186        entryOf(k4, v4),
187        entryOf(k5, v5),
188        entryOf(k6, v6),
189        entryOf(k7, v7));
190  }
191
192  /**
193   * Returns an immutable sorted map containing the given entries, sorted by the natural ordering of
194   * their keys.
195   *
196   * @throws IllegalArgumentException if any two keys are equal according to their natural ordering
197   * @since 31.0
198   */
199  @SuppressWarnings("unchecked")
200  public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V> of(
201      K k1,
202      V v1,
203      K k2,
204      V v2,
205      K k3,
206      V v3,
207      K k4,
208      V v4,
209      K k5,
210      V v5,
211      K k6,
212      V v6,
213      K k7,
214      V v7,
215      K k8,
216      V v8) {
217    return fromEntries(
218        entryOf(k1, v1),
219        entryOf(k2, v2),
220        entryOf(k3, v3),
221        entryOf(k4, v4),
222        entryOf(k5, v5),
223        entryOf(k6, v6),
224        entryOf(k7, v7),
225        entryOf(k8, v8));
226  }
227
228  /**
229   * Returns an immutable sorted map containing the given entries, sorted by the natural ordering of
230   * their keys.
231   *
232   * @throws IllegalArgumentException if any two keys are equal according to their natural ordering
233   * @since 31.0
234   */
235  @SuppressWarnings("unchecked")
236  public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V> of(
237      K k1,
238      V v1,
239      K k2,
240      V v2,
241      K k3,
242      V v3,
243      K k4,
244      V v4,
245      K k5,
246      V v5,
247      K k6,
248      V v6,
249      K k7,
250      V v7,
251      K k8,
252      V v8,
253      K k9,
254      V v9) {
255    return fromEntries(
256        entryOf(k1, v1),
257        entryOf(k2, v2),
258        entryOf(k3, v3),
259        entryOf(k4, v4),
260        entryOf(k5, v5),
261        entryOf(k6, v6),
262        entryOf(k7, v7),
263        entryOf(k8, v8),
264        entryOf(k9, v9));
265  }
266
267  /**
268   * Returns an immutable sorted map containing the given entries, sorted by the natural ordering of
269   * their keys.
270   *
271   * @throws IllegalArgumentException if any two keys are equal according to their natural ordering
272   * @since 31.0
273   */
274  @SuppressWarnings("unchecked")
275  public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V> of(
276      K k1,
277      V v1,
278      K k2,
279      V v2,
280      K k3,
281      V v3,
282      K k4,
283      V v4,
284      K k5,
285      V v5,
286      K k6,
287      V v6,
288      K k7,
289      V v7,
290      K k8,
291      V v8,
292      K k9,
293      V v9,
294      K k10,
295      V v10) {
296    return fromEntries(
297        entryOf(k1, v1),
298        entryOf(k2, v2),
299        entryOf(k3, v3),
300        entryOf(k4, v4),
301        entryOf(k5, v5),
302        entryOf(k6, v6),
303        entryOf(k7, v7),
304        entryOf(k8, v8),
305        entryOf(k9, v9),
306        entryOf(k10, v10));
307  }
308
309  /**
310   * Returns an immutable map containing the same entries as {@code map}, sorted by the natural
311   * ordering of the keys.
312   *
313   * <p>Despite the method name, this method attempts to avoid actually copying the data when it is
314   * safe to do so. The exact circumstances under which a copy will or will not be performed are
315   * undocumented and subject to change.
316   *
317   * <p>This method is not type-safe, as it may be called on a map with keys that are not mutually
318   * comparable.
319   *
320   * @throws ClassCastException if the keys in {@code map} are not mutually comparable
321   * @throws NullPointerException if any key or value in {@code map} is null
322   * @throws IllegalArgumentException if any two keys are equal according to their natural ordering
323   */
324  public static <K, V> ImmutableSortedMap<K, V> copyOf(Map<? extends K, ? extends V> map) {
325    // Hack around K not being a subtype of Comparable.
326    // Unsafe, see ImmutableSortedSetFauxverideShim.
327    @SuppressWarnings("unchecked")
328    Ordering<K> naturalOrder = (Ordering<K>) NATURAL_ORDER;
329    return copyOfInternal(map, naturalOrder);
330  }
331
332  /**
333   * Returns an immutable map containing the same entries as {@code map}, with keys sorted by the
334   * provided comparator.
335   *
336   * <p>Despite the method name, this method attempts to avoid actually copying the data when it is
337   * safe to do so. The exact circumstances under which a copy will or will not be performed are
338   * undocumented and subject to change.
339   *
340   * @throws NullPointerException if any key or value in {@code map} is null
341   * @throws IllegalArgumentException if any two keys are equal according to the comparator
342   */
343  public static <K, V> ImmutableSortedMap<K, V> copyOf(
344      Map<? extends K, ? extends V> map, Comparator<? super K> comparator) {
345    return copyOfInternal(map, checkNotNull(comparator));
346  }
347
348  /**
349   * Returns an immutable map containing the given entries, with keys sorted by their natural
350   * ordering.
351   *
352   * <p>This method is not type-safe, as it may be called on a map with keys that are not mutually
353   * comparable.
354   *
355   * @throws NullPointerException if any key or value in {@code map} is null
356   * @throws IllegalArgumentException if any two keys are equal according to the comparator
357   * @since 19.0
358   */
359  @Beta
360  public static <K, V> ImmutableSortedMap<K, V> copyOf(
361      Iterable<? extends Entry<? extends K, ? extends V>> entries) {
362    // Hack around K not being a subtype of Comparable.
363    // Unsafe, see ImmutableSortedSetFauxverideShim.
364    @SuppressWarnings("unchecked")
365    Ordering<K> naturalOrder = (Ordering<K>) NATURAL_ORDER;
366    return copyOf(entries, naturalOrder);
367  }
368
369  /**
370   * Returns an immutable map containing the given entries, with keys sorted by the provided
371   * comparator.
372   *
373   * @throws NullPointerException if any key or value in {@code map} is null
374   * @throws IllegalArgumentException if any two keys are equal according to the comparator
375   * @since 19.0
376   */
377  @Beta
378  public static <K, V> ImmutableSortedMap<K, V> copyOf(
379      Iterable<? extends Entry<? extends K, ? extends V>> entries,
380      Comparator<? super K> comparator) {
381    return fromEntries(checkNotNull(comparator), false, entries);
382  }
383
384  /**
385   * Returns an immutable map containing the same entries as the provided sorted map, with the same
386   * ordering.
387   *
388   * <p>Despite the method name, this method attempts to avoid actually copying the data when it is
389   * safe to do so. The exact circumstances under which a copy will or will not be performed are
390   * undocumented and subject to change.
391   *
392   * @throws NullPointerException if any key or value in {@code map} is null
393   */
394  @SuppressWarnings("unchecked")
395  public static <K, V> ImmutableSortedMap<K, V> copyOfSorted(SortedMap<K, ? extends V> map) {
396    Comparator<? super K> comparator = map.comparator();
397    if (comparator == null) {
398      // If map has a null comparator, the keys should have a natural ordering,
399      // even though K doesn't explicitly implement Comparable.
400      comparator = (Comparator<? super K>) NATURAL_ORDER;
401    }
402    if (map instanceof ImmutableSortedMap) {
403      // TODO(kevinb): Prove that this cast is safe, even though
404      // Collections.unmodifiableSortedMap requires the same key type.
405      @SuppressWarnings("unchecked")
406      ImmutableSortedMap<K, V> kvMap = (ImmutableSortedMap<K, V>) map;
407      if (!kvMap.isPartialView()) {
408        return kvMap;
409      }
410    }
411    return fromEntries(comparator, true, map.entrySet());
412  }
413
414  private static <K, V> ImmutableSortedMap<K, V> copyOfInternal(
415      Map<? extends K, ? extends V> map, Comparator<? super K> comparator) {
416    boolean sameComparator = false;
417    if (map instanceof SortedMap) {
418      SortedMap<?, ?> sortedMap = (SortedMap<?, ?>) map;
419      Comparator<?> comparator2 = sortedMap.comparator();
420      sameComparator =
421          (comparator2 == null) ? comparator == NATURAL_ORDER : comparator.equals(comparator2);
422    }
423
424    if (sameComparator && (map instanceof ImmutableSortedMap)) {
425      // TODO(kevinb): Prove that this cast is safe, even though
426      // Collections.unmodifiableSortedMap requires the same key type.
427      @SuppressWarnings("unchecked")
428      ImmutableSortedMap<K, V> kvMap = (ImmutableSortedMap<K, V>) map;
429      if (!kvMap.isPartialView()) {
430        return kvMap;
431      }
432    }
433    return fromEntries(comparator, sameComparator, map.entrySet());
434  }
435
436  private static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V> fromEntries(
437      Entry<K, V>... entries) {
438    return fromEntries(Ordering.natural(), false, entries, entries.length);
439  }
440
441  /**
442   * Accepts a collection of possibly-null entries. If {@code sameComparator}, then it is assumed
443   * that they do not need to be sorted or checked for dupes.
444   */
445  private static <K, V> ImmutableSortedMap<K, V> fromEntries(
446      Comparator<? super K> comparator,
447      boolean sameComparator,
448      Iterable<? extends Entry<? extends K, ? extends V>> entries) {
449    // "adding" type params to an array of a raw type should be safe as
450    // long as no one can ever cast that same array instance back to a
451    // raw type.
452    @SuppressWarnings("unchecked")
453    Entry<K, V>[] entryArray = (Entry[]) Iterables.toArray(entries, EMPTY_ENTRY_ARRAY);
454    return fromEntries(comparator, sameComparator, entryArray, entryArray.length);
455  }
456
457  private static <K, V> ImmutableSortedMap<K, V> fromEntries(
458      final Comparator<? super K> comparator,
459      boolean sameComparator,
460      @Nullable Entry<K, V>[] entryArray,
461      int size) {
462    switch (size) {
463      case 0:
464        return emptyMap(comparator);
465      case 1:
466        // requireNonNull is safe because the first `size` elements have been filled in.
467        Entry<K, V> onlyEntry = requireNonNull(entryArray[0]);
468        return of(comparator, onlyEntry.getKey(), onlyEntry.getValue());
469      default:
470        Object[] keys = new Object[size];
471        Object[] values = new Object[size];
472        if (sameComparator) {
473          // Need to check for nulls, but don't need to sort or validate.
474          for (int i = 0; i < size; i++) {
475            // requireNonNull is safe because the first `size` elements have been filled in.
476            Entry<K, V> entry = requireNonNull(entryArray[i]);
477            Object key = entry.getKey();
478            Object value = entry.getValue();
479            checkEntryNotNull(key, value);
480            keys[i] = key;
481            values[i] = value;
482          }
483        } else {
484          // Need to sort and check for nulls and dupes.
485          // Inline the Comparator implementation rather than transforming with a Function
486          // to save code size.
487          Arrays.sort(
488              entryArray,
489              0,
490              size,
491              new Comparator<@Nullable Entry<K, V>>() {
492                @Override
493                public int compare(@CheckForNull Entry<K, V> e1, @CheckForNull Entry<K, V> e2) {
494                  // requireNonNull is safe because the first `size` elements have been filled in.
495                  requireNonNull(e1);
496                  requireNonNull(e2);
497                  return comparator.compare(e1.getKey(), e2.getKey());
498                }
499              });
500          // requireNonNull is safe because the first `size` elements have been filled in.
501          Entry<K, V> firstEntry = requireNonNull(entryArray[0]);
502          K prevKey = firstEntry.getKey();
503          keys[0] = prevKey;
504          values[0] = firstEntry.getValue();
505          checkEntryNotNull(keys[0], values[0]);
506          for (int i = 1; i < size; i++) {
507            // requireNonNull is safe because the first `size` elements have been filled in.
508            Entry<K, V> prevEntry = requireNonNull(entryArray[i - 1]);
509            Entry<K, V> entry = requireNonNull(entryArray[i]);
510            K key = entry.getKey();
511            V value = entry.getValue();
512            checkEntryNotNull(key, value);
513            keys[i] = key;
514            values[i] = value;
515            checkNoConflict(comparator.compare(prevKey, key) != 0, "key", prevEntry, entry);
516            prevKey = key;
517          }
518        }
519        return new ImmutableSortedMap<>(
520            new RegularImmutableSortedSet<K>(ImmutableList.<K>asImmutableList(keys), comparator),
521            ImmutableList.<V>asImmutableList(values));
522    }
523  }
524
525  /**
526   * Returns a builder that creates immutable sorted maps whose keys are ordered by their natural
527   * ordering. The sorted maps use {@link Ordering#natural()} as the comparator.
528   */
529  public static <K extends Comparable<?>, V> Builder<K, V> naturalOrder() {
530    return new Builder<>(Ordering.natural());
531  }
532
533  /**
534   * Returns a builder that creates immutable sorted maps with an explicit comparator. If the
535   * comparator has a more general type than the map's keys, such as creating a {@code
536   * SortedMap<Integer, String>} with a {@code Comparator<Number>}, use the {@link Builder}
537   * constructor instead.
538   *
539   * @throws NullPointerException if {@code comparator} is null
540   */
541  public static <K, V> Builder<K, V> orderedBy(Comparator<K> comparator) {
542    return new Builder<>(comparator);
543  }
544
545  /**
546   * Returns a builder that creates immutable sorted maps whose keys are ordered by the reverse of
547   * their natural ordering.
548   */
549  public static <K extends Comparable<?>, V> Builder<K, V> reverseOrder() {
550    return new Builder<>(Ordering.natural().reverse());
551  }
552
553  /**
554   * A builder for creating immutable sorted map instances, especially {@code public static final}
555   * maps ("constant maps"). Example:
556   *
557   * <pre>{@code
558   * static final ImmutableSortedMap<Integer, String> INT_TO_WORD =
559   *     new ImmutableSortedMap.Builder<Integer, String>(Ordering.natural())
560   *         .put(1, "one")
561   *         .put(2, "two")
562   *         .put(3, "three")
563   *         .buildOrThrow();
564   * }</pre>
565   *
566   * <p>For <i>small</i> immutable sorted maps, the {@code ImmutableSortedMap.of()} methods are even
567   * more convenient.
568   *
569   * <p>Builder instances can be reused - it is safe to call {@link #buildOrThrow} multiple times to
570   * build multiple maps in series. Each map is a superset of the maps created before it.
571   *
572   * @since 2.0
573   */
574  public static class Builder<K, V> extends ImmutableMap.Builder<K, V> {
575    private transient @Nullable Object[] keys;
576    private transient @Nullable Object[] values;
577    private final Comparator<? super K> comparator;
578
579    /**
580     * Creates a new builder. The returned builder is equivalent to the builder generated by {@link
581     * ImmutableSortedMap#orderedBy}.
582     */
583    @SuppressWarnings("unchecked")
584    public Builder(Comparator<? super K> comparator) {
585      this(comparator, ImmutableCollection.Builder.DEFAULT_INITIAL_CAPACITY);
586    }
587
588    private Builder(Comparator<? super K> comparator, int initialCapacity) {
589      this.comparator = checkNotNull(comparator);
590      this.keys = new @Nullable Object[initialCapacity];
591      this.values = new @Nullable Object[initialCapacity];
592    }
593
594    private void ensureCapacity(int minCapacity) {
595      if (minCapacity > keys.length) {
596        int newCapacity = ImmutableCollection.Builder.expandedCapacity(keys.length, minCapacity);
597        this.keys = Arrays.copyOf(keys, newCapacity);
598        this.values = Arrays.copyOf(values, newCapacity);
599      }
600    }
601
602    /**
603     * Associates {@code key} with {@code value} in the built map. Duplicate keys, according to the
604     * comparator (which might be the keys' natural order), are not allowed, and will cause {@link
605     * #build} to fail.
606     */
607    @CanIgnoreReturnValue
608    @Override
609    public Builder<K, V> put(K key, V value) {
610      ensureCapacity(size + 1);
611      checkEntryNotNull(key, value);
612      keys[size] = key;
613      values[size] = value;
614      size++;
615      return this;
616    }
617
618    /**
619     * Adds the given {@code entry} to the map, making it immutable if necessary. Duplicate keys,
620     * according to the comparator (which might be the keys' natural order), are not allowed, and
621     * will cause {@link #build} to fail.
622     *
623     * @since 11.0
624     */
625    @CanIgnoreReturnValue
626    @Override
627    public Builder<K, V> put(Entry<? extends K, ? extends V> entry) {
628      super.put(entry);
629      return this;
630    }
631
632    /**
633     * Associates all of the given map's keys and values in the built map. Duplicate keys, according
634     * to the comparator (which might be the keys' natural order), are not allowed, and will cause
635     * {@link #build} to fail.
636     *
637     * @throws NullPointerException if any key or value in {@code map} is null
638     */
639    @CanIgnoreReturnValue
640    @Override
641    public Builder<K, V> putAll(Map<? extends K, ? extends V> map) {
642      super.putAll(map);
643      return this;
644    }
645
646    /**
647     * Adds all the given entries to the built map. Duplicate keys, according to the comparator
648     * (which might be the keys' natural order), are not allowed, and will cause {@link #build} to
649     * fail.
650     *
651     * @throws NullPointerException if any key, value, or entry is null
652     * @since 19.0
653     */
654    @CanIgnoreReturnValue
655    @Beta
656    @Override
657    public Builder<K, V> putAll(Iterable<? extends Entry<? extends K, ? extends V>> entries) {
658      super.putAll(entries);
659      return this;
660    }
661
662    /**
663     * Throws an {@code UnsupportedOperationException}.
664     *
665     * @since 19.0
666     * @deprecated Unsupported by ImmutableSortedMap.Builder.
667     */
668    @CanIgnoreReturnValue
669    @Beta
670    @Override
671    @Deprecated
672    @DoNotCall("Always throws UnsupportedOperationException")
673    public final Builder<K, V> orderEntriesByValue(Comparator<? super V> valueComparator) {
674      throw new UnsupportedOperationException("Not available on ImmutableSortedMap.Builder");
675    }
676
677    @CanIgnoreReturnValue
678    Builder<K, V> combine(ImmutableSortedMap.Builder<K, V> other) {
679      ensureCapacity(size + other.size);
680      System.arraycopy(other.keys, 0, this.keys, this.size, other.size);
681      System.arraycopy(other.values, 0, this.values, this.size, other.size);
682      size += other.size;
683      return this;
684    }
685
686    /**
687     * Returns a newly-created immutable sorted map.
688     *
689     * <p>Prefer the equivalent method {@link #buildOrThrow()} to make it explicit that the method
690     * will throw an exception if there are duplicate keys. The {@code build()} method will soon be
691     * deprecated.
692     *
693     * @throws IllegalArgumentException if any two keys are equal according to the comparator (which
694     *     might be the keys' natural order)
695     */
696    @Override
697    public ImmutableSortedMap<K, V> build() {
698      return buildOrThrow();
699    }
700
701    /**
702     * Returns a newly-created immutable sorted map, or throws an exception if any two keys are
703     * equal.
704     *
705     * @throws IllegalArgumentException if any two keys are equal according to the comparator (which
706     *     might be the keys' natural order)
707     * @since 31.0
708     */
709    @Override
710    public ImmutableSortedMap<K, V> buildOrThrow() {
711      switch (size) {
712        case 0:
713          return emptyMap(comparator);
714        case 1:
715          // requireNonNull is safe because the first `size` elements have been filled in.
716          return of(comparator, (K) requireNonNull(keys[0]), (V) requireNonNull(values[0]));
717        default:
718          Object[] sortedKeys = Arrays.copyOf(keys, size);
719          Arrays.sort((K[]) sortedKeys, comparator);
720          Object[] sortedValues = new Object[size];
721
722          // We might, somehow, be able to reorder values in-place.  But it doesn't seem like
723          // there's a way around creating the separate sortedKeys array, and if we're allocating
724          // one array of size n, we might as well allocate two -- to say nothing of the allocation
725          // done in Arrays.sort.
726          for (int i = 0; i < size; i++) {
727            if (i > 0 && comparator.compare((K) sortedKeys[i - 1], (K) sortedKeys[i]) == 0) {
728              throw new IllegalArgumentException(
729                  "keys required to be distinct but compared as equal: "
730                      + sortedKeys[i - 1]
731                      + " and "
732                      + sortedKeys[i]);
733            }
734            // requireNonNull is safe because the first `size` elements have been filled in.
735            int index =
736                Arrays.binarySearch((K[]) sortedKeys, (K) requireNonNull(keys[i]), comparator);
737            sortedValues[index] = requireNonNull(values[i]);
738          }
739          return new ImmutableSortedMap<K, V>(
740              new RegularImmutableSortedSet<K>(
741                  ImmutableList.<K>asImmutableList(sortedKeys), comparator),
742              ImmutableList.<V>asImmutableList(sortedValues));
743      }
744    }
745
746    /**
747     * Throws UnsupportedOperationException. A future version may support this operation. Then the
748     * value for any given key will be the one that was last supplied in a {@code put} operation for
749     * that key.
750     *
751     * @throws UnsupportedOperationException always
752     * @since 31.1
753     * @deprecated This method is not currently implemented, and may never be.
754     */
755    @DoNotCall
756    @Deprecated
757    @Override
758    public final ImmutableSortedMap<K, V> buildKeepingLast() {
759      // TODO(emcmanus): implement
760      throw new UnsupportedOperationException(
761          "ImmutableSortedMap.Builder does not yet implement buildKeepingLast()");
762    }
763  }
764
765  private final transient RegularImmutableSortedSet<K> keySet;
766  private final transient ImmutableList<V> valueList;
767  @CheckForNull private transient ImmutableSortedMap<K, V> descendingMap;
768
769  ImmutableSortedMap(RegularImmutableSortedSet<K> keySet, ImmutableList<V> valueList) {
770    this(keySet, valueList, null);
771  }
772
773  ImmutableSortedMap(
774      RegularImmutableSortedSet<K> keySet,
775      ImmutableList<V> valueList,
776      @CheckForNull ImmutableSortedMap<K, V> descendingMap) {
777    this.keySet = keySet;
778    this.valueList = valueList;
779    this.descendingMap = descendingMap;
780  }
781
782  @Override
783  public int size() {
784    return valueList.size();
785  }
786
787  @Override
788  @CheckForNull
789  public V get(@CheckForNull Object key) {
790    int index = keySet.indexOf(key);
791    return (index == -1) ? null : valueList.get(index);
792  }
793
794  @Override
795  boolean isPartialView() {
796    return keySet.isPartialView() || valueList.isPartialView();
797  }
798
799  /** Returns an immutable set of the mappings in this map, sorted by the key ordering. */
800  @Override
801  public ImmutableSet<Entry<K, V>> entrySet() {
802    return super.entrySet();
803  }
804
805  @Override
806  ImmutableSet<Entry<K, V>> createEntrySet() {
807    class EntrySet extends ImmutableMapEntrySet<K, V> {
808      @Override
809      public UnmodifiableIterator<Entry<K, V>> iterator() {
810        return asList().iterator();
811      }
812
813      @Override
814      ImmutableList<Entry<K, V>> createAsList() {
815        return new ImmutableList<Entry<K, V>>() {
816          @Override
817          public Entry<K, V> get(int index) {
818            return new AbstractMap.SimpleImmutableEntry<>(
819                keySet.asList().get(index), valueList.get(index));
820          }
821
822          @Override
823          boolean isPartialView() {
824            return true;
825          }
826
827          @Override
828          public int size() {
829            return ImmutableSortedMap.this.size();
830          }
831        };
832      }
833
834      @Override
835      ImmutableMap<K, V> map() {
836        return ImmutableSortedMap.this;
837      }
838    }
839    return isEmpty() ? ImmutableSet.<Entry<K, V>>of() : new EntrySet();
840  }
841
842  /** Returns an immutable sorted set of the keys in this map. */
843  @Override
844  public ImmutableSortedSet<K> keySet() {
845    return keySet;
846  }
847
848  @Override
849  ImmutableSet<K> createKeySet() {
850    throw new AssertionError("should never be called");
851  }
852
853  /**
854   * Returns an immutable collection of the values in this map, sorted by the ordering of the
855   * corresponding keys.
856   */
857  @Override
858  public ImmutableCollection<V> values() {
859    return valueList;
860  }
861
862  @Override
863  ImmutableCollection<V> createValues() {
864    throw new AssertionError("should never be called");
865  }
866
867  /**
868   * Returns the comparator that orders the keys, which is {@link Ordering#natural()} when the
869   * natural ordering of the keys is used. Note that its behavior is not consistent with {@link
870   * TreeMap#comparator()}, which returns {@code null} to indicate natural ordering.
871   */
872  @Override
873  public Comparator<? super K> comparator() {
874    return keySet().comparator();
875  }
876
877  @Override
878  public K firstKey() {
879    return keySet().first();
880  }
881
882  @Override
883  public K lastKey() {
884    return keySet().last();
885  }
886
887  private ImmutableSortedMap<K, V> getSubMap(int fromIndex, int toIndex) {
888    if (fromIndex == 0 && toIndex == size()) {
889      return this;
890    } else if (fromIndex == toIndex) {
891      return emptyMap(comparator());
892    } else {
893      return new ImmutableSortedMap<>(
894          keySet.getSubSet(fromIndex, toIndex), valueList.subList(fromIndex, toIndex));
895    }
896  }
897
898  /**
899   * This method returns a {@code ImmutableSortedMap}, consisting of the entries whose keys are less
900   * than {@code toKey}.
901   *
902   * <p>The {@link SortedMap#headMap} documentation states that a submap of a submap throws an
903   * {@link IllegalArgumentException} if passed a {@code toKey} greater than an earlier {@code
904   * toKey}. However, this method doesn't throw an exception in that situation, but instead keeps
905   * the original {@code toKey}.
906   */
907  @Override
908  public ImmutableSortedMap<K, V> headMap(K toKey) {
909    return headMap(toKey, false);
910  }
911
912  /**
913   * This method returns a {@code ImmutableSortedMap}, consisting of the entries whose keys are less
914   * than (or equal to, if {@code inclusive}) {@code toKey}.
915   *
916   * <p>The {@link SortedMap#headMap} documentation states that a submap of a submap throws an
917   * {@link IllegalArgumentException} if passed a {@code toKey} greater than an earlier {@code
918   * toKey}. However, this method doesn't throw an exception in that situation, but instead keeps
919   * the original {@code toKey}.
920   *
921   * @since 12.0
922   */
923  @Override
924  public ImmutableSortedMap<K, V> headMap(K toKey, boolean inclusive) {
925    return getSubMap(0, keySet.headIndex(checkNotNull(toKey), inclusive));
926  }
927
928  /**
929   * This method returns a {@code ImmutableSortedMap}, consisting of the entries whose keys ranges
930   * from {@code fromKey}, inclusive, to {@code toKey}, exclusive.
931   *
932   * <p>The {@link SortedMap#subMap} documentation states that a submap of a submap throws an {@link
933   * IllegalArgumentException} if passed a {@code fromKey} less than an earlier {@code fromKey}.
934   * However, this method doesn't throw an exception in that situation, but instead keeps the
935   * original {@code fromKey}. Similarly, this method keeps the original {@code toKey}, instead of
936   * throwing an exception, if passed a {@code toKey} greater than an earlier {@code toKey}.
937   */
938  @Override
939  public ImmutableSortedMap<K, V> subMap(K fromKey, K toKey) {
940    return subMap(fromKey, true, toKey, false);
941  }
942
943  /**
944   * This method returns a {@code ImmutableSortedMap}, consisting of the entries whose keys ranges
945   * from {@code fromKey} to {@code toKey}, inclusive or exclusive as indicated by the boolean
946   * flags.
947   *
948   * <p>The {@link SortedMap#subMap} documentation states that a submap of a submap throws an {@link
949   * IllegalArgumentException} if passed a {@code fromKey} less than an earlier {@code fromKey}.
950   * However, this method doesn't throw an exception in that situation, but instead keeps the
951   * original {@code fromKey}. Similarly, this method keeps the original {@code toKey}, instead of
952   * throwing an exception, if passed a {@code toKey} greater than an earlier {@code toKey}.
953   *
954   * @since 12.0
955   */
956  @Override
957  public ImmutableSortedMap<K, V> subMap(
958      K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
959    checkNotNull(fromKey);
960    checkNotNull(toKey);
961    checkArgument(
962        comparator().compare(fromKey, toKey) <= 0,
963        "expected fromKey <= toKey but %s > %s",
964        fromKey,
965        toKey);
966    return headMap(toKey, toInclusive).tailMap(fromKey, fromInclusive);
967  }
968
969  /**
970   * This method returns a {@code ImmutableSortedMap}, consisting of the entries whose keys are
971   * greater than or equals to {@code fromKey}.
972   *
973   * <p>The {@link SortedMap#tailMap} documentation states that a submap of a submap throws an
974   * {@link IllegalArgumentException} if passed a {@code fromKey} less than an earlier {@code
975   * fromKey}. However, this method doesn't throw an exception in that situation, but instead keeps
976   * the original {@code fromKey}.
977   */
978  @Override
979  public ImmutableSortedMap<K, V> tailMap(K fromKey) {
980    return tailMap(fromKey, true);
981  }
982
983  /**
984   * This method returns a {@code ImmutableSortedMap}, consisting of the entries whose keys are
985   * greater than (or equal to, if {@code inclusive}) {@code fromKey}.
986   *
987   * <p>The {@link SortedMap#tailMap} documentation states that a submap of a submap throws an
988   * {@link IllegalArgumentException} if passed a {@code fromKey} less than an earlier {@code
989   * fromKey}. However, this method doesn't throw an exception in that situation, but instead keeps
990   * the original {@code fromKey}.
991   *
992   * @since 12.0
993   */
994  @Override
995  public ImmutableSortedMap<K, V> tailMap(K fromKey, boolean inclusive) {
996    return getSubMap(keySet.tailIndex(checkNotNull(fromKey), inclusive), size());
997  }
998
999  @Override
1000  @CheckForNull
1001  public Entry<K, V> lowerEntry(K key) {
1002    return headMap(key, false).lastEntry();
1003  }
1004
1005  @Override
1006  @CheckForNull
1007  public K lowerKey(K key) {
1008    return keyOrNull(lowerEntry(key));
1009  }
1010
1011  @Override
1012  @CheckForNull
1013  public Entry<K, V> floorEntry(K key) {
1014    return headMap(key, true).lastEntry();
1015  }
1016
1017  @Override
1018  @CheckForNull
1019  public K floorKey(K key) {
1020    return keyOrNull(floorEntry(key));
1021  }
1022
1023  @Override
1024  @CheckForNull
1025  public Entry<K, V> ceilingEntry(K key) {
1026    return tailMap(key, true).firstEntry();
1027  }
1028
1029  @Override
1030  @CheckForNull
1031  public K ceilingKey(K key) {
1032    return keyOrNull(ceilingEntry(key));
1033  }
1034
1035  @Override
1036  @CheckForNull
1037  public Entry<K, V> higherEntry(K key) {
1038    return tailMap(key, false).firstEntry();
1039  }
1040
1041  @Override
1042  @CheckForNull
1043  public K higherKey(K key) {
1044    return keyOrNull(higherEntry(key));
1045  }
1046
1047  @Override
1048  @CheckForNull
1049  public Entry<K, V> firstEntry() {
1050    return isEmpty() ? null : entrySet().asList().get(0);
1051  }
1052
1053  @Override
1054  @CheckForNull
1055  public Entry<K, V> lastEntry() {
1056    return isEmpty() ? null : entrySet().asList().get(size() - 1);
1057  }
1058
1059  /**
1060   * Guaranteed to throw an exception and leave the map unmodified.
1061   *
1062   * @throws UnsupportedOperationException always
1063   * @deprecated Unsupported operation.
1064   */
1065  @CanIgnoreReturnValue
1066  @Deprecated
1067  @Override
1068  @DoNotCall("Always throws UnsupportedOperationException")
1069  @CheckForNull
1070  public final Entry<K, V> pollFirstEntry() {
1071    throw new UnsupportedOperationException();
1072  }
1073
1074  /**
1075   * Guaranteed to throw an exception and leave the map unmodified.
1076   *
1077   * @throws UnsupportedOperationException always
1078   * @deprecated Unsupported operation.
1079   */
1080  @CanIgnoreReturnValue
1081  @Deprecated
1082  @Override
1083  @DoNotCall("Always throws UnsupportedOperationException")
1084  @CheckForNull
1085  public final Entry<K, V> pollLastEntry() {
1086    throw new UnsupportedOperationException();
1087  }
1088
1089  @Override
1090  public ImmutableSortedMap<K, V> descendingMap() {
1091    // TODO(kevinb): the descendingMap is never actually cached at all. Either it should be or the
1092    // code below simplified.
1093    ImmutableSortedMap<K, V> result = descendingMap;
1094    if (result == null) {
1095      if (isEmpty()) {
1096        return result = emptyMap(Ordering.from(comparator()).reverse());
1097      } else {
1098        return result =
1099            new ImmutableSortedMap<>(
1100                (RegularImmutableSortedSet<K>) keySet.descendingSet(), valueList.reverse(), this);
1101      }
1102    }
1103    return result;
1104  }
1105
1106  @Override
1107  public ImmutableSortedSet<K> navigableKeySet() {
1108    return keySet;
1109  }
1110
1111  @Override
1112  public ImmutableSortedSet<K> descendingKeySet() {
1113    return keySet.descendingSet();
1114  }
1115
1116  /**
1117   * Serialized type for all ImmutableSortedMap instances. It captures the logical contents and they
1118   * are reconstructed using public factory methods. This ensures that the implementation types
1119   * remain as implementation details.
1120   */
1121  private static class SerializedForm<K, V> extends ImmutableMap.SerializedForm<K, V> {
1122    private final Comparator<? super K> comparator;
1123
1124    SerializedForm(ImmutableSortedMap<K, V> sortedMap) {
1125      super(sortedMap);
1126      comparator = sortedMap.comparator();
1127    }
1128
1129    @Override
1130    Builder<K, V> makeBuilder(int size) {
1131      return new Builder<>(comparator);
1132    }
1133
1134    private static final long serialVersionUID = 0;
1135  }
1136
1137  @Override
1138  Object writeReplace() {
1139    return new SerializedForm<>(this);
1140  }
1141
1142  // This class is never actually serialized directly, but we have to make the
1143  // warning go away (and suppressing would suppress for all nested classes too)
1144  private static final long serialVersionUID = 0;
1145}