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