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