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