    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
    017    package com.google.common.collect;
    018
    019    import static com.google.common.base.Preconditions.checkArgument;
    020    import static com.google.common.base.Preconditions.checkNotNull;
    021    import static com.google.common.collect.Maps.keyOrNull;
    022
    023    import com.google.common.annotations.GwtCompatible;
    024
    025    import java.util.Arrays;
    026    import java.util.Collection;
    027    import java.util.Collections;
    028    import java.util.Comparator;
    029    import java.util.List;
    030    import java.util.Map;
    031    import java.util.NavigableMap;
    032    import java.util.SortedMap;
    033    import java.util.TreeMap;
    034
    035    import javax.annotation.Nullable;
    036
    037    /**
    038     * An immutable {@link SortedMap}. Does not permit null keys or values.
    039     *
    040     * <p>Unlike {@link Collections#unmodifiableSortedMap}, which is a <i>view</i>
    041     * of a separate map which can still change, an instance of {@code
    042     * ImmutableSortedMap} contains its own data and will <i>never</i> change.
    043     * {@code ImmutableSortedMap} is convenient for {@code public static final} maps
    044     * ("constant maps") and also lets you easily make a "defensive copy" of a map
    045     * provided to your class by a caller.
    046     *
    047     * <p><b>Note:</b> Although this class is not final, it cannot be subclassed as
    048     * it has no public or protected constructors. Thus, instances of this class are
    049     * guaranteed to be immutable.
    050     *
    051     * <p>See the Guava User Guide article on <a href=
    052     * "http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained">
    053     * immutable collections</a>.
    054     *
    055     * @author Jared Levy
    056     * @author Louis Wasserman
    057     * @since 2.0 (imported from Google Collections Library; implements {@code
    058     *        NavigableMap} since 12.0)
    059     */
    060    @GwtCompatible(serializable = true, emulated = true)
    061    public abstract class ImmutableSortedMap<K, V>
    062        extends ImmutableSortedMapFauxverideShim<K, V> implements NavigableMap<K, V> {
    063      /*
    064       * TODO(kevinb): Confirm that ImmutableSortedMap is faster to construct and
    065       * uses less memory than TreeMap; then say so in the class Javadoc.
    066       */
    067      private static final Comparator<Comparable> NATURAL_ORDER = Ordering.natural();
    068
    069      private static final ImmutableSortedMap<Comparable, Object> NATURAL_EMPTY_MAP =
    070          new EmptyImmutableSortedMap<Comparable, Object>(NATURAL_ORDER);
    071
    072      static <K, V> ImmutableSortedMap<K, V> emptyMap(Comparator<? super K> comparator) {
    073        if (Ordering.natural().equals(comparator)) {
    074          return of();
    075        } else {
    076          return new EmptyImmutableSortedMap<K, V>(comparator);
    077        }
    078      }
    079
    080      static <K, V> ImmutableSortedMap<K, V> fromSortedEntries(
    081          Comparator<? super K> comparator,
    082          Collection<? extends Entry<? extends K, ? extends V>> entries) {
    083        if (entries.isEmpty()) {
    084          return emptyMap(comparator);
    085        }
    086
    087        ImmutableList.Builder<K> keyBuilder = ImmutableList.builder();
    088        ImmutableList.Builder<V> valueBuilder = ImmutableList.builder();
    089        for (Entry<? extends K, ? extends V> entry : entries) {
    090          keyBuilder.add(entry.getKey());
    091          valueBuilder.add(entry.getValue());
    092        }
    093
    094        return new RegularImmutableSortedMap<K, V>(
    095            new RegularImmutableSortedSet<K>(keyBuilder.build(), comparator),
    096            valueBuilder.build());
    097      }
    098
    099      static <K, V> ImmutableSortedMap<K, V> from(
    100          ImmutableSortedSet<K> keySet, ImmutableList<V> valueList) {
    101        if (keySet.isEmpty()) {
    102          return emptyMap(keySet.comparator());
    103        } else {
    104          return new RegularImmutableSortedMap<K, V>(
    105              (RegularImmutableSortedSet<K>) keySet,
    106              valueList);
    107        }
    108      }
    109
    110      /**
    111       * Returns the empty sorted map.
    112       */
    113      @SuppressWarnings("unchecked")
    114      // unsafe, comparator() returns a comparator on the specified type
    115      // TODO(kevinb): evaluate whether or not of().comparator() should return null
    116      public static <K, V> ImmutableSortedMap<K, V> of() {
    117        return (ImmutableSortedMap<K, V>) NATURAL_EMPTY_MAP;
    118      }
    119
    120      /**
    121       * Returns an immutable map containing a single entry.
    122       */
    123      public static <K extends Comparable<? super K>, V>
    124          ImmutableSortedMap<K, V> of(K k1, V v1) {
    125        return from(ImmutableSortedSet.of(k1), ImmutableList.of(v1));
    126      }
    127
    128      /**
    129       * Returns an immutable sorted map containing the given entries, sorted by the
    130       * natural ordering of their keys.
    131       *
    132       * @throws IllegalArgumentException if the two keys are equal according to
    133       *     their natural ordering
    134       */
    135      public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V>
    136          of(K k1, V v1, K k2, V v2) {
    137        return new Builder<K, V>(Ordering.natural())
    138            .put(k1, v1).put(k2, v2).build();
    139      }
    140
    141      /**
    142       * Returns an immutable sorted map containing the given entries, sorted by the
    143       * natural ordering of their keys.
    144       *
    145       * @throws IllegalArgumentException if any two keys are equal according to
    146       *     their natural ordering
    147       */
    148      public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V>
    149          of(K k1, V v1, K k2, V v2, K k3, V v3) {
    150        return new Builder<K, V>(Ordering.natural())
    151            .put(k1, v1).put(k2, v2).put(k3, v3).build();
    152      }
    153
    154      /**
    155       * Returns an immutable sorted map containing the given entries, sorted by the
    156       * natural ordering of their keys.
    157       *
    158       * @throws IllegalArgumentException if any two keys are equal according to
    159       *     their natural ordering
    160       */
    161      public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V>
    162          of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
    163        return new Builder<K, V>(Ordering.natural())
    164            .put(k1, v1).put(k2, v2).put(k3, v3).put(k4, v4).build();
    165      }
    166
    167      /**
    168       * Returns an immutable sorted map containing the given entries, sorted by the
    169       * natural ordering of their keys.
    170       *
    171       * @throws IllegalArgumentException if any two keys are equal according to
    172       *     their natural ordering
    173       */
    174      public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V>
    175          of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
    176        return new Builder<K, V>(Ordering.natural())
    177            .put(k1, v1).put(k2, v2).put(k3, v3).put(k4, v4).put(k5, v5).build();
    178      }
    179
    180      /**
    181       * Returns an immutable map containing the same entries as {@code map}, sorted
    182       * by the natural ordering of the keys.
    183       *
    184       * <p>Despite the method name, this method attempts to avoid actually copying
    185       * the data when it is safe to do so. The exact circumstances under which a
    186       * copy will or will not be performed are undocumented and subject to change.
    187       *
    188       * <p>This method is not type-safe, as it may be called on a map with keys
    189       * that are not mutually comparable.
    190       *
    191       * @throws ClassCastException if the keys in {@code map} are not mutually
    192       *         comparable
    193       * @throws NullPointerException if any key or value in {@code map} is null
    194       * @throws IllegalArgumentException if any two keys are equal according to
    195       *         their natural ordering
    196       */
    197      public static <K, V> ImmutableSortedMap<K, V> copyOf(
    198          Map<? extends K, ? extends V> map) {
    199        // Hack around K not being a subtype of Comparable.
    200        // Unsafe, see ImmutableSortedSetFauxverideShim.
    201        @SuppressWarnings("unchecked")
    202        Ordering<K> naturalOrder = (Ordering<K>) Ordering.<Comparable>natural();
    203        return copyOfInternal(map, naturalOrder);
    204      }
    205
    206      /**
    207       * Returns an immutable map containing the same entries as {@code map}, with
    208       * keys sorted by the provided comparator.
    209       *
    210       * <p>Despite the method name, this method attempts to avoid actually copying
    211       * the data when it is safe to do so. The exact circumstances under which a
    212       * copy will or will not be performed are undocumented and subject to change.
    213       *
    214       * @throws NullPointerException if any key or value in {@code map} is null
    215       * @throws IllegalArgumentException if any two keys are equal according to the
    216       *         comparator
    217       */
    218      public static <K, V> ImmutableSortedMap<K, V> copyOf(
    219          Map<? extends K, ? extends V> map, Comparator<? super K> comparator) {
    220        return copyOfInternal(map, checkNotNull(comparator));
    221      }
    222
    223      /**
    224       * Returns an immutable map containing the same entries as the provided sorted
    225       * map, with the same ordering.
    226       *
    227       * <p>Despite the method name, this method attempts to avoid actually copying
    228       * the data when it is safe to do so. The exact circumstances under which a
    229       * copy will or will not be performed are undocumented and subject to change.
    230       *
    231       * @throws NullPointerException if any key or value in {@code map} is null
    232       */
    233      @SuppressWarnings("unchecked")
    234      public static <K, V> ImmutableSortedMap<K, V> copyOfSorted(
    235          SortedMap<K, ? extends V> map) {
    236        Comparator<? super K> comparator = map.comparator();
    237        if (comparator == null) {
    238          // If map has a null comparator, the keys should have a natural ordering,
    239          // even though K doesn't explicitly implement Comparable.
    240          comparator = (Comparator<? super K>) NATURAL_ORDER;
    241        }
    242        return copyOfInternal(map, comparator);
    243      }
    244
    245      private static <K, V> ImmutableSortedMap<K, V> copyOfInternal(
    246          Map<? extends K, ? extends V> map, Comparator<? super K> comparator) {
    247        boolean sameComparator = false;
    248        if (map instanceof SortedMap) {
    249          SortedMap<?, ?> sortedMap = (SortedMap<?, ?>) map;
    250          Comparator<?> comparator2 = sortedMap.comparator();
    251          sameComparator = (comparator2 == null)
    252              ? comparator == NATURAL_ORDER
    253              : comparator.equals(comparator2);
    254        }
    255
    256        if (sameComparator && (map instanceof ImmutableSortedMap)) {
    257          // TODO(kevinb): Prove that this cast is safe, even though
    258          // Collections.unmodifiableSortedMap requires the same key type.
    259          @SuppressWarnings("unchecked")
    260          ImmutableSortedMap<K, V> kvMap = (ImmutableSortedMap<K, V>) map;
    261          if (!kvMap.isPartialView()) {
    262            return kvMap;
    263          }
    264        }
    265
    266        // "adding" type params to an array of a raw type should be safe as
    267        // long as no one can ever cast that same array instance back to a
    268        // raw type.
    269        @SuppressWarnings("unchecked")
    270        Entry<K, V>[] entries = map.entrySet().toArray(new Entry[0]);
    271
    272        for (int i = 0; i < entries.length; i++) {
    273          Entry<K, V> entry = entries[i];
    274          entries[i] = entryOf(entry.getKey(), entry.getValue());
    275        }
    276
    277        List<Entry<K, V>> list = Arrays.asList(entries);
    278
    279        if (!sameComparator) {
    280          sortEntries(list, comparator);
    281          validateEntries(list, comparator);
    282        }
    283
    284        return fromSortedEntries(comparator, list);
    285      }
    286
    287      private static <K, V> void sortEntries(
    288          List<Entry<K, V>> entries, final Comparator<? super K> comparator) {
    289        Comparator<Entry<K, V>> entryComparator = new Comparator<Entry<K, V>>() {
    290
    291          @Override public int compare(Entry<K, V> entry1, Entry<K, V> entry2) {
    292            return comparator.compare(entry1.getKey(), entry2.getKey());
    293          }
    294        };
    295
    296        Collections.sort(entries, entryComparator);
    297      }
    298
    299      private static <K, V> void validateEntries(List<Entry<K, V>> entries,
    300          Comparator<? super K> comparator) {
    301        for (int i = 1; i < entries.size(); i++) {
    302          if (comparator.compare(
    303              entries.get(i - 1).getKey(), entries.get(i).getKey()) == 0) {
    304            throw new IllegalArgumentException(
    305                "Duplicate keys in mappings " + entries.get(i - 1) + " and "
    306                    + entries.get(i));
    307          }
    308        }
    309      }
    310
    311      /**
    312       * Returns a builder that creates immutable sorted maps whose keys are
    313       * ordered by their natural ordering. The sorted maps use {@link
    314       * Ordering#natural()} as the comparator.
    315       *
    316       * <p>Note: the type parameter {@code K} extends {@code Comparable<K>} rather
    317       * than {@code Comparable<? super K>} as a workaround for javac <a
    318       * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6468354">bug
    319       * 6468354</a>.
    320       */
    321      public static <K extends Comparable<K>, V> Builder<K, V> naturalOrder() {
    322        return new Builder<K, V>(Ordering.natural());
    323      }
    324
    325      /**
    326       * Returns a builder that creates immutable sorted maps with an explicit
    327       * comparator. If the comparator has a more general type than the map's keys,
    328       * such as creating a {@code SortedMap<Integer, String>} with a {@code
    329       * Comparator<Number>}, use the {@link Builder} constructor instead.
    330       *
    331       * @throws NullPointerException if {@code comparator} is null
    332       */
    333      public static <K, V> Builder<K, V> orderedBy(Comparator<K> comparator) {
    334        return new Builder<K, V>(comparator);
    335      }
    336
    337      /**
    338       * Returns a builder that creates immutable sorted maps whose keys are
    339       * ordered by the reverse of their natural ordering.
    340       *
    341       * <p>Note: the type parameter {@code K} extends {@code Comparable<K>} rather
    342       * than {@code Comparable<? super K>} as a workaround for javac <a
    343       * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6468354">bug
    344       * 6468354</a>.
    345       */
    346      public static <K extends Comparable<K>, V> Builder<K, V> reverseOrder() {
    347        return new Builder<K, V>(Ordering.natural().reverse());
    348      }
    349
    350      /**
    351       * A builder for creating immutable sorted map instances, especially {@code
    352       * public static final} maps ("constant maps"). Example: <pre>   {@code
    353       *
    354       *   static final ImmutableSortedMap<Integer, String> INT_TO_WORD =
    355       *       new ImmutableSortedMap.Builder<Integer, String>(Ordering.natural())
    356       *           .put(1, "one")
    357       *           .put(2, "two")
    358       *           .put(3, "three")
    359       *           .build();}</pre>
    360       *
    361       * For <i>small</i> immutable sorted maps, the {@code ImmutableSortedMap.of()}
    362       * methods are even more convenient.
    363       *
    364       * <p>Builder instances can be reused - it is safe to call {@link #build}
    365       * multiple times to build multiple maps in series. Each map is a superset of
    366       * the maps created before it.
    367       *
    368       * @since 2.0 (imported from Google Collections Library)
    369       */
    370      public static class Builder<K, V> extends ImmutableMap.Builder<K, V> {
    371        private final Comparator<? super K> comparator;
    372
    373        /**
    374         * Creates a new builder. The returned builder is equivalent to the builder
    375         * generated by {@link ImmutableSortedMap#orderedBy}.
    376         */
    377        public Builder(Comparator<? super K> comparator) {
    378          this.comparator = checkNotNull(comparator);
    379        }
    380
    381        /**
    382         * Associates {@code key} with {@code value} in the built map. Duplicate
    383         * keys, according to the comparator (which might be the keys' natural
    384         * order), are not allowed, and will cause {@link #build} to fail.
    385         */
    386        @Override public Builder<K, V> put(K key, V value) {
    387          entries.add(entryOf(key, value));
    388          return this;
    389        }
    390
    391        /**
    392         * Adds the given {@code entry} to the map, making it immutable if
    393         * necessary. Duplicate keys, according to the comparator (which might be
    394         * the keys' natural order), are not allowed, and will cause {@link #build}
    395         * to fail.
    396         *
    397         * @since 11.0
    398         */
    399        @Override public Builder<K, V> put(Entry<? extends K, ? extends V> entry) {
    400          super.put(entry);
    401          return this;
    402        }
    403
    404        /**
    405         * Associates all of the given map's keys and values in the built map.
    406         * Duplicate keys, according to the comparator (which might be the keys'
    407         * natural order), are not allowed, and will cause {@link #build} to fail.
    408         *
    409         * @throws NullPointerException if any key or value in {@code map} is null
    410         */
    411        @Override public Builder<K, V> putAll(Map<? extends K, ? extends V> map) {
    412          for (Entry<? extends K, ? extends V> entry : map.entrySet()) {
    413            put(entry.getKey(), entry.getValue());
    414          }
    415          return this;
    416        }
    417
    418        /**
    419         * Returns a newly-created immutable sorted map.
    420         *
    421         * @throws IllegalArgumentException if any two keys are equal according to
    422         *     the comparator (which might be the keys' natural order)
    423         */
    424        @Override public ImmutableSortedMap<K, V> build() {
    425          sortEntries(entries, comparator);
    426          validateEntries(entries, comparator);
    427          return fromSortedEntries(comparator, entries);
    428        }
    429      }
    430
    431      ImmutableSortedMap() {
    432      }
    433
    434      ImmutableSortedMap(ImmutableSortedMap<K, V> descendingMap) {
    435        this.descendingMap = descendingMap;
    436      }
    437
    438      @Override
    439      public int size() {
    440        return values().size();
    441      }
    442
    443      @Override public boolean containsValue(@Nullable Object value) {
    444        return values().contains(value);
    445      }
    446
    447      @Override boolean isPartialView() {
    448        return keySet().isPartialView() || values().isPartialView();
    449      }
    450
    451      /**
    452       * Returns an immutable set of the mappings in this map, sorted by the key
    453       * ordering.
    454       */
    455      @Override public ImmutableSet<Entry<K, V>> entrySet() {
    456        return super.entrySet();
    457      }
    458
    459      /**
    460       * Returns an immutable sorted set of the keys in this map.
    461       */
    462      @Override public abstract ImmutableSortedSet<K> keySet();
    463
    464      /**
    465       * Returns an immutable collection of the values in this map, sorted by the
    466       * ordering of the corresponding keys.
    467       */
    468      @Override public abstract ImmutableCollection<V> values();
    469
    470      /**
    471       * Returns the comparator that orders the keys, which is
    472       * {@link Ordering#natural()} when the natural ordering of the keys is used.
    473       * Note that its behavior is not consistent with {@link TreeMap#comparator()},
    474       * which returns {@code null} to indicate natural ordering.
    475       */
    476      @Override
    477      public Comparator<? super K> comparator() {
    478        return keySet().comparator();
    479      }
    480
    481      @Override
    482      public K firstKey() {
    483        return keySet().first();
    484      }
    485
    486      @Override
    487      public K lastKey() {
    488        return keySet().last();
    489      }
    490
    491      /**
    492       * This method returns a {@code ImmutableSortedMap}, consisting of the entries
    493       * whose keys are less than {@code toKey}.
    494       *
    495       * <p>The {@link SortedMap#headMap} documentation states that a submap of a
    496       * submap throws an {@link IllegalArgumentException} if passed a {@code toKey}
    497       * greater than an earlier {@code toKey}. However, this method doesn't throw
    498       * an exception in that situation, but instead keeps the original {@code
    499       * toKey}.
    500       */
    501      @Override
    502      public ImmutableSortedMap<K, V> headMap(K toKey) {
    503        return headMap(toKey, false);
    504      }
    505
    506      /**
    507       * This method returns a {@code ImmutableSortedMap}, consisting of the entries
    508       * whose keys are less than (or equal to, if {@code inclusive}) {@code toKey}.
    509       *
    510       * <p>The {@link SortedMap#headMap} documentation states that a submap of a
    511       * submap throws an {@link IllegalArgumentException} if passed a {@code toKey}
    512       * greater than an earlier {@code toKey}. However, this method doesn't throw
    513       * an exception in that situation, but instead keeps the original {@code
    514       * toKey}.
    515       *
    516       * @since 12.0
    517       */
    518      @Override
    519      public abstract ImmutableSortedMap<K, V> headMap(K toKey, boolean inclusive);
    520
    521      /**
    522       * This method returns a {@code ImmutableSortedMap}, consisting of the entries
    523       * whose keys ranges from {@code fromKey}, inclusive, to {@code toKey},
    524       * exclusive.
    525       *
    526       * <p>The {@link SortedMap#subMap} documentation states that a submap of a
    527       * submap throws an {@link IllegalArgumentException} if passed a {@code
    528       * fromKey} less than an earlier {@code fromKey}. However, this method doesn't
    529       * throw an exception in that situation, but instead keeps the original {@code
    530       * fromKey}. Similarly, this method keeps the original {@code toKey}, instead
    531       * of throwing an exception, if passed a {@code toKey} greater than an earlier
    532       * {@code toKey}.
    533       */
    534      @Override
    535      public ImmutableSortedMap<K, V> subMap(K fromKey, K toKey) {
    536        return subMap(fromKey, true, toKey, false);
    537      }
    538
    539      /**
    540       * This method returns a {@code ImmutableSortedMap}, consisting of the entries
    541       * whose keys ranges from {@code fromKey} to {@code toKey}, inclusive or
    542       * exclusive as indicated by the boolean flags.
    543       *
    544       * <p>The {@link SortedMap#subMap} documentation states that a submap of a
    545       * submap throws an {@link IllegalArgumentException} if passed a {@code
    546       * fromKey} less than an earlier {@code fromKey}. However, this method doesn't
    547       * throw an exception in that situation, but instead keeps the original {@code
    548       * fromKey}. Similarly, this method keeps the original {@code toKey}, instead
    549       * of throwing an exception, if passed a {@code toKey} greater than an earlier
    550       * {@code toKey}.
    551       *
    552       * @since 12.0
    553       */
    554      @Override
    555      public ImmutableSortedMap<K, V> subMap(K fromKey, boolean fromInclusive, K toKey,
    556          boolean toInclusive) {
    557        checkNotNull(fromKey);
    558        checkNotNull(toKey);
    559        checkArgument(comparator().compare(fromKey, toKey) <= 0,
    560            "expected fromKey <= toKey but %s > %s", fromKey, toKey);
    561        return headMap(toKey, toInclusive).tailMap(fromKey, fromInclusive);
    562      }
    563
    564      /**
    565       * This method returns a {@code ImmutableSortedMap}, consisting of the entries
    566       * whose keys are greater than or equals to {@code fromKey}.
    567       *
    568       * <p>The {@link SortedMap#tailMap} documentation states that a submap of a
    569       * submap throws an {@link IllegalArgumentException} if passed a {@code
    570       * fromKey} less than an earlier {@code fromKey}. However, this method doesn't
    571       * throw an exception in that situation, but instead keeps the original {@code
    572       * fromKey}.
    573       */
    574      @Override
    575      public ImmutableSortedMap<K, V> tailMap(K fromKey) {
    576        return tailMap(fromKey, true);
    577      }
    578
    579      /**
    580       * This method returns a {@code ImmutableSortedMap}, consisting of the entries
    581       * whose keys are greater than (or equal to, if {@code inclusive})
    582       * {@code fromKey}.
    583       *
    584       * <p>The {@link SortedMap#tailMap} documentation states that a submap of a
    585       * submap throws an {@link IllegalArgumentException} if passed a {@code
    586       * fromKey} less than an earlier {@code fromKey}. However, this method doesn't
    587       * throw an exception in that situation, but instead keeps the original {@code
    588       * fromKey}.
    589       *
    590       * @since 12.0
    591       */
    592      @Override
    593      public abstract ImmutableSortedMap<K, V> tailMap(K fromKey, boolean inclusive);
    594
    595      @Override
    596      public Entry<K, V> lowerEntry(K key) {
    597        return headMap(key, false).lastEntry();
    598      }
    599
    600      @Override
    601      public K lowerKey(K key) {
    602        return keyOrNull(lowerEntry(key));
    603      }
    604
    605      @Override
    606      public Entry<K, V> floorEntry(K key) {
    607        return headMap(key, true).lastEntry();
    608      }
    609
    610      @Override
    611      public K floorKey(K key) {
    612        return keyOrNull(floorEntry(key));
    613      }
    614
    615      @Override
    616      public Entry<K, V> ceilingEntry(K key) {
    617        return tailMap(key, true).firstEntry();
    618      }
    619
    620      @Override
    621      public K ceilingKey(K key) {
    622        return keyOrNull(ceilingEntry(key));
    623      }
    624
    625      @Override
    626      public Entry<K, V> higherEntry(K key) {
    627        return tailMap(key, false).firstEntry();
    628      }
    629
    630      @Override
    631      public K higherKey(K key) {
    632        return keyOrNull(higherEntry(key));
    633      }
    634
    635      @Override
    636      public Entry<K, V> firstEntry() {
    637        return isEmpty() ? null : entrySet().asList().get(0);
    638      }
    639
    640      @Override
    641      public Entry<K, V> lastEntry() {
    642        return isEmpty() ? null : entrySet().asList().get(size() - 1);
    643      }
    644
    645      @Override
    646      public final Entry<K, V> pollFirstEntry() {
    647        throw new UnsupportedOperationException();
    648      }
    649
    650      @Override
    651      public final Entry<K, V> pollLastEntry() {
    652        throw new UnsupportedOperationException();
    653      }
    654
    655      private transient ImmutableSortedMap<K, V> descendingMap;
    656
    657      @Override
    658      public ImmutableSortedMap<K, V> descendingMap() {
    659        ImmutableSortedMap<K, V> result = descendingMap;
    660        if (result == null) {
    661          result = descendingMap = createDescendingMap();
    662        }
    663        return result;
    664      }
    665
    666      abstract ImmutableSortedMap<K, V> createDescendingMap();
    667
    668      @Override
    669      public ImmutableSortedSet<K> navigableKeySet() {
    670        return keySet();
    671      }
    672
    673      @Override
    674      public ImmutableSortedSet<K> descendingKeySet() {
    675        return keySet().descendingSet();
    676      }
    677
    678      /**
    679       * Serialized type for all ImmutableSortedMap instances. It captures the
    680       * logical contents and they are reconstructed using public factory methods.
    681       * This ensures that the implementation types remain as implementation
    682       * details.
    683       */
    684      private static class SerializedForm extends ImmutableMap.SerializedForm {
    685        private final Comparator<Object> comparator;
    686        @SuppressWarnings("unchecked")
    687        SerializedForm(ImmutableSortedMap<?, ?> sortedMap) {
    688          super(sortedMap);
    689          comparator = (Comparator<Object>) sortedMap.comparator();
    690        }
    691        @Override Object readResolve() {
    692          Builder<Object, Object> builder = new Builder<Object, Object>(comparator);
    693          return createMap(builder);
    694        }
    695        private static final long serialVersionUID = 0;
    696      }
    697
    698      @Override Object writeReplace() {
    699        return new SerializedForm(this);
    700      }
    701
    702      // This class is never actually serialized directly, but we have to make the
    703      // warning go away (and suppressing would suppress for all nested classes too)
    704      private static final long serialVersionUID = 0;
    705    }