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