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