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