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    }