001    /*
002     * Copyright (C) 2008 Google Inc.
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    
022    import com.google.common.annotations.Beta;
023    import com.google.common.annotations.GwtCompatible;
024    
025    import java.io.InvalidObjectException;
026    import java.io.ObjectInputStream;
027    import java.io.Serializable;
028    import java.util.ArrayList;
029    import java.util.Arrays;
030    import java.util.Collection;
031    import java.util.Collections;
032    import java.util.Comparator;
033    import java.util.Iterator;
034    import java.util.List;
035    import java.util.SortedSet;
036    
037    /**
038     * An immutable {@code SortedSet} that stores its elements in a sorted array.
039     * Some instances are ordered by an explicit comparator, while others follow the
040     * natural sort ordering of their elements. Either way, null elements are not
041     * supported.
042     *
043     * <p>Unlike {@link Collections#unmodifiableSortedSet}, which is a <i>view</i>
044     * of a separate collection that can still change, an instance of {@code
045     * ImmutableSortedSet} contains its own private data and will <i>never</i>
046     * change. This class is convenient for {@code public static final} sets
047     * ("constant sets") and also lets you easily make a "defensive copy" of a set
048     * provided to your class by a caller.
049     *
050     * <p>The sets returned by {@link #headSet}, {@link #tailSet}, and
051     * {@link #subSet} methods share the same array as the original set, preventing
052     * that array from being garbage collected. If this is a concern, the data may
053     * be copied into a correctly-sized array by calling {@link #copyOfSorted}.
054     *
055     * <p><b>Note on element equivalence:</b> The {@link #contains(Object)},
056     * {@link #containsAll(Collection)}, and {@link #equals(Object)}
057     * implementations must check whether a provided object is equivalent to an
058     * element in the collection. Unlike most collections, an
059     * {@code ImmutableSortedSet} doesn't use {@link Object#equals} to determine if
060     * two elements are equivalent. Instead, with an explicit comparator, the
061     * following relation determines whether elements {@code x} and {@code y} are
062     * equivalent: <pre>   {@code
063     *
064     *   {(x, y) | comparator.compare(x, y) == 0}}</pre>
065     *
066     * With natural ordering of elements, the following relation determines whether
067     * two elements are equivalent: <pre>   {@code
068     *
069     *   {(x, y) | x.compareTo(y) == 0}}</pre>
070     *
071     * <b>Warning:</b> Like most sets, an {@code ImmutableSortedSet} will not
072     * function correctly if an element is modified after being placed in the set.
073     * For this reason, and to avoid general confusion, it is strongly recommended
074     * to place only immutable objects into this collection.
075     *
076     * <p><b>Note</b>: Although this class is not final, it cannot be subclassed as
077     * it has no public or protected constructors. Thus, instances of this type are
078     * guaranteed to be immutable.
079     *
080     * @see ImmutableSet
081     * @author Jared Levy
082     * @since 2 (imported from Google Collections Library)
083     */
084    // TODO: benchmark and optimize all creation paths, which are a mess right now
085    @GwtCompatible(serializable = true, emulated = true)
086    @SuppressWarnings("serial") // we're overriding default serialization
087    public abstract class ImmutableSortedSet<E>
088        extends ImmutableSortedSetFauxverideShim<E> implements SortedSet<E> {
089    
090      // TODO: Can we find a way to remove this @SuppressWarnings even for eclipse?
091      @SuppressWarnings("unchecked")
092      private static final Comparator NATURAL_ORDER = Ordering.natural();
093    
094      @SuppressWarnings("unchecked")
095      private static final ImmutableSortedSet<Object> NATURAL_EMPTY_SET =
096          new EmptyImmutableSortedSet<Object>(NATURAL_ORDER);
097    
098      @SuppressWarnings("unchecked")
099      private static <E> ImmutableSortedSet<E> emptySet() {
100        return (ImmutableSortedSet<E>) NATURAL_EMPTY_SET;
101      }
102    
103      static <E> ImmutableSortedSet<E> emptySet(
104          Comparator<? super E> comparator) {
105        if (NATURAL_ORDER.equals(comparator)) {
106          return emptySet();
107        } else {
108          return new EmptyImmutableSortedSet<E>(comparator);
109        }
110      }
111    
112      /**
113       * Returns the empty immutable sorted set.
114       */
115      public static <E> ImmutableSortedSet<E> of() {
116        return emptySet();
117      }
118    
119      /**
120       * Returns an immutable sorted set containing a single element.
121       */
122      public static <E extends Comparable<? super E>> ImmutableSortedSet<E> of(
123          E element) {
124        Object[] array = { checkNotNull(element) };
125        return new RegularImmutableSortedSet<E>(array, Ordering.natural());
126      }
127    
128      /**
129       * Returns an immutable sorted set containing the given elements sorted by
130       * their natural ordering. When multiple elements are equivalent according to
131       * {@link Comparable#compareTo}, only the first one specified is included.
132       *
133       * @throws NullPointerException if any element is null
134       */
135      @SuppressWarnings("unchecked")
136      public static <E extends Comparable<? super E>> ImmutableSortedSet<E> of(
137          E e1, E e2) {
138        return ofInternal(Ordering.natural(), e1, e2);
139      }
140    
141      /**
142       * Returns an immutable sorted set containing the given elements sorted by
143       * their natural ordering. When multiple elements are equivalent according to
144       * {@link Comparable#compareTo}, only the first one specified is included.
145       *
146       * @throws NullPointerException if any element is null
147       */
148      @SuppressWarnings("unchecked")
149      public static <E extends Comparable<? super E>> ImmutableSortedSet<E> of(
150          E e1, E e2, E e3) {
151        return ofInternal(Ordering.natural(), e1, e2, e3);
152      }
153    
154      /**
155       * Returns an immutable sorted set containing the given elements sorted by
156       * their natural ordering. When multiple elements are equivalent according to
157       * {@link Comparable#compareTo}, only the first one specified is included.
158       *
159       * @throws NullPointerException if any element is null
160       */
161      @SuppressWarnings("unchecked")
162      public static <E extends Comparable<? super E>> ImmutableSortedSet<E> of(
163          E e1, E e2, E e3, E e4) {
164        return ofInternal(Ordering.natural(), e1, e2, e3, e4);
165      }
166    
167      /**
168       * Returns an immutable sorted set containing the given elements sorted by
169       * their natural ordering. When multiple elements are equivalent according to
170       * {@link Comparable#compareTo}, only the first one specified is included.
171       *
172       * @throws NullPointerException if any element is null
173       */
174      @SuppressWarnings("unchecked")
175      public static <E extends Comparable<? super E>> ImmutableSortedSet<E> of(
176          E e1, E e2, E e3, E e4, E e5) {
177        return ofInternal(Ordering.natural(), e1, e2, e3, e4, e5);
178      }
179      
180      /**
181       * Returns an immutable sorted set containing the given elements sorted by
182       * their natural ordering. When multiple elements are equivalent according to
183       * {@link Comparable#compareTo}, only the first one specified is included.
184       *
185       * @throws NullPointerException if any element is null
186       * @since 3 (source-compatible since release 2)
187       */
188      @SuppressWarnings("unchecked")
189      public static <E extends Comparable<? super E>> ImmutableSortedSet<E> of(
190          E e1, E e2, E e3, E e4, E e5, E e6, E... remaining) {
191        int size = remaining.length + 6;
192        List<E> all = new ArrayList<E>(size);
193        Collections.addAll(all, e1, e2, e3, e4, e5, e6);
194        Collections.addAll(all, remaining);
195        // This is a mess (see TODO at top of file)
196        return ofInternal(Ordering.natural(),
197            (Object[]) all.toArray(new Comparable[0]));
198      }
199    
200      // TODO: Consider adding factory methods that throw an exception when given
201      // duplicate elements.
202    
203      /**
204       * Returns an immutable sorted set containing the given elements sorted by
205       * their natural ordering. When multiple elements are equivalent according to
206       * {@link Comparable#compareTo}, only the first one specified is included.
207       *
208       * @throws NullPointerException if any of {@code elements} is null
209       * @deprecated use {@link #copyOf(Comparable[])}.
210       * @since 2 (changed from varargs in release 3)
211       */
212      @Deprecated
213      public static <E extends Comparable<? super E>> ImmutableSortedSet<E> of(
214          E[] elements) {
215        return copyOf(elements);
216      }
217      
218      /**
219       * Returns an immutable sorted set containing the given elements sorted by
220       * their natural ordering. When multiple elements are equivalent according to
221       * {@link Comparable#compareTo}, only the first one specified is included.
222       *
223       * @throws NullPointerException if any of {@code elements} is null
224       * @since 3
225       */
226      public static <E extends Comparable<? super E>> ImmutableSortedSet<E> copyOf(
227          E[] elements) {
228        return ofInternal(Ordering.natural(), (Object[]) elements);
229      }
230    
231      private static <E> ImmutableSortedSet<E> ofInternal(
232          Comparator<? super E> comparator, Object... elements) {
233        switch (elements.length) {
234          case 0:
235            return emptySet(comparator);
236          default:
237            /*
238             * We can't use Platform.clone() because of GWT bug 3621. See our GWT
239             * ImmutableSortedSetTest.testOf_gwtArraycopyBug() for details. We can't
240             * use System.arraycopy() here for the same reason.
241             */
242            Object[] array = new Object[elements.length];
243            for (int i = 0; i < elements.length; i++) {
244              array[i] = checkNotNull(elements[i]);
245            }
246            sort(array, comparator);
247            array = removeDupes(array, comparator);
248            return new RegularImmutableSortedSet<E>(array, comparator);
249        }
250      }
251    
252      /** Sort the array, according to the comparator. */
253      @SuppressWarnings("unchecked") // E comparator with Object array
254      private static <E> void sort(
255          Object[] array, Comparator<? super E> comparator) {
256        Arrays.sort(array, (Comparator<Object>) comparator);
257      }
258    
259      /**
260       * Returns an array that removes duplicate consecutive elements, according to
261       * the provided comparator. Note that the input array is modified. This method
262       * does not support empty arrays.
263       */
264      private static <E> Object[] removeDupes(Object[] array,
265          Comparator<? super E> comparator) {
266        int size = 1;
267        for (int i = 1; i < array.length; i++) {
268          Object element = array[i];
269          if (unsafeCompare(comparator, array[size - 1], element) != 0) {
270            array[size] = element;
271            size++;
272          }
273        }
274    
275        // TODO: Move to ObjectArrays?
276        if (size == array.length) {
277          return array;
278        } else {
279          Object[] copy = new Object[size];
280          Platform.unsafeArrayCopy(array, 0, copy, 0, size);
281          return copy;
282        }
283      }
284    
285      /**
286       * Returns an immutable sorted set containing the given elements sorted by
287       * their natural ordering. When multiple elements are equivalent according to
288       * {@code compareTo()}, only the first one specified is included. To create a
289       * copy of a {@code SortedSet} that preserves the comparator, call
290       * {@link #copyOfSorted} instead. This method iterates over {@code elements}
291       * at most once.
292       *
293       * <p>Note that if {@code s} is a {@code Set<String>}, then
294       * {@code ImmutableSortedSet.copyOf(s)} returns an
295       * {@code ImmutableSortedSet<String>} containing each of the strings in
296       * {@code s}, while {@code ImmutableSortedSet.of(s)} returns an
297       * {@code ImmutableSortedSet<Set<String>>} containing one element (the given
298       * set itself).
299       *
300       * <p><b>Note:</b> Despite what the method name suggests, if {@code elements}
301       * is an {@code ImmutableSortedSet}, it may be returned instead of a copy.
302       *
303       * <p>This method is not type-safe, as it may be called on elements that are
304       * not mutually comparable.
305       *
306       * @throws ClassCastException if the elements are not mutually comparable
307       * @throws NullPointerException if any of {@code elements} is null
308       */
309      public static <E> ImmutableSortedSet<E> copyOf(
310          Iterable<? extends E> elements) {
311        // Hack around K not being a subtype of Comparable.
312        // Unsafe, see ImmutableSortedSetFauxverideShim.
313        @SuppressWarnings("unchecked")
314        Ordering<E> naturalOrder = (Ordering) Ordering.<Comparable>natural();
315        return copyOfInternal(naturalOrder, elements, false);
316      }
317    
318      /**
319       * Returns an immutable sorted set containing the given elements sorted by
320       * their natural ordering. When multiple elements are equivalent according to
321       * {@code compareTo()}, only the first one specified is included.
322       *
323       * <p>This method is not type-safe, as it may be called on elements that are
324       * not mutually comparable.
325       *
326       * @throws ClassCastException if the elements are not mutually comparable
327       * @throws NullPointerException if any of {@code elements} is null
328       */
329      public static <E> ImmutableSortedSet<E> copyOf(
330          Iterator<? extends E> elements) {
331        // Hack around K not being a subtype of Comparable.
332        // Unsafe, see ImmutableSortedSetFauxverideShim.
333        @SuppressWarnings("unchecked")
334        Ordering<E> naturalOrder = (Ordering) Ordering.<Comparable>natural();
335        return copyOfInternal(naturalOrder, elements);
336      }
337    
338      /**
339       * Returns an immutable sorted set containing the given elements sorted by
340       * the given {@code Comparator}. When multiple elements are equivalent
341       * according to {@code compare()}, only the first one specified is
342       * included. This method iterates over {@code elements} at most once.
343       *
344       * <p><b>Note:</b> Despite what the method name suggests, if {@code elements}
345       * is an {@code ImmutableSortedSet}, it may be returned instead of a copy.
346       *
347       * @throws NullPointerException if {@code comparator} or any of
348       *     {@code elements} is null
349       */
350      public static <E> ImmutableSortedSet<E> copyOf(
351          Comparator<? super E> comparator, Iterable<? extends E> elements) {
352        checkNotNull(comparator);
353        return copyOfInternal(comparator, elements, false);
354      }
355    
356      /**
357       * Returns an immutable sorted set containing the given elements sorted by
358       * the given {@code Comparator}. When multiple elements are equivalent
359       * according to {@code compareTo()}, only the first one specified is
360       * included.
361       *
362       * @throws NullPointerException if {@code comparator} or any of
363       *     {@code elements} is null
364       */
365      public static <E> ImmutableSortedSet<E> copyOf(
366          Comparator<? super E> comparator, Iterator<? extends E> elements) {
367        checkNotNull(comparator);
368        return copyOfInternal(comparator, elements);
369      }
370    
371      /**
372       * Returns an immutable sorted set containing the elements of a sorted set,
373       * sorted by the same {@code Comparator}. That behavior differs from
374       * {@link #copyOf(Iterable)}, which always uses the natural ordering of the
375       * elements.
376       *
377       * <p><b>Note:</b> Despite what the method name suggests, if {@code sortedSet}
378       * is an {@code ImmutableSortedSet}, it may be returned instead of a copy.
379       *
380       * @throws NullPointerException if {@code sortedSet} or any of its elements
381       *     is null
382       */
383      @SuppressWarnings("unchecked")
384      public static <E> ImmutableSortedSet<E> copyOfSorted(SortedSet<E> sortedSet) {
385        Comparator<? super E> comparator = sortedSet.comparator();
386        if (comparator == null) {
387          comparator = NATURAL_ORDER;
388        }
389        return copyOfInternal(comparator, sortedSet, true);
390      }
391    
392      private static <E> ImmutableSortedSet<E> copyOfInternal(
393          Comparator<? super E> comparator, Iterable<? extends E> elements,
394          boolean fromSortedSet) {
395        boolean hasSameComparator
396            = fromSortedSet || hasSameComparator(elements, comparator);
397    
398        if (hasSameComparator && (elements instanceof ImmutableSortedSet)) {
399          @SuppressWarnings("unchecked")
400          ImmutableSortedSet<E> result = (ImmutableSortedSet<E>) elements;
401          if (!result.hasPartialArray()) {
402            return result;
403          }
404        }
405    
406        Object[] array = newObjectArray(elements);
407        if (array.length == 0) {
408          return emptySet(comparator);
409        }
410    
411        for (Object e : array) {
412          checkNotNull(e);
413        }
414        if (!hasSameComparator) {
415          sort(array, comparator);
416          array = removeDupes(array, comparator);
417        }
418        return new RegularImmutableSortedSet<E>(array, comparator);
419      }
420    
421      /** Simplified version of {@link Iterables#toArray} that is GWT safe. */
422      private static <T> Object[] newObjectArray(Iterable<T> iterable) {
423        Collection<T> collection = Collections2.toCollection(iterable);
424        Object[] array = new Object[collection.size()];
425        return collection.toArray(array);
426      }
427    
428      private static <E> ImmutableSortedSet<E> copyOfInternal(
429          Comparator<? super E> comparator, Iterator<? extends E> elements) {
430        if (!elements.hasNext()) {
431          return emptySet(comparator);
432        }
433        List<E> list = Lists.newArrayList();
434        while (elements.hasNext()) {
435          list.add(checkNotNull(elements.next()));
436        }
437        Object[] array = list.toArray();
438        sort(array, comparator);
439        array = removeDupes(array, comparator);
440        return new RegularImmutableSortedSet<E>(array, comparator);
441      }
442    
443      /**
444       * Returns {@code true} if {@code elements} is a {@code SortedSet} that uses
445       * {@code comparator} to order its elements. Note that equivalent comparators
446       * may still return {@code false}, if {@code equals} doesn't consider them
447       * equal. If one comparator is {@code null} and the other is
448       * {@link Ordering#natural()}, this method returns {@code true}.
449       */
450      static boolean hasSameComparator(
451          Iterable<?> elements, Comparator<?> comparator) {
452        if (elements instanceof SortedSet) {
453          SortedSet<?> sortedSet = (SortedSet<?>) elements;
454          Comparator<?> comparator2 = sortedSet.comparator();
455          return (comparator2 == null)
456              ? comparator == Ordering.natural()
457              : comparator.equals(comparator2);
458        }
459        return false;
460      }
461    
462      /**
463       * Returns an immutable sorted set containing the elements in the given list
464       * in the same order. It is useful when the elements already have the desired
465       * order but constructing the appropriate comparator is difficult.
466       *
467       * @throws NullPointerException if any of the elements is null
468       * @throws IllegalArgumentException if {@code elements} contains any
469       *     duplicate values (according to {@link Object#equals})
470       * @since 3
471       */
472      @Beta
473      public static <E> ImmutableSortedSet<E> withExplicitOrder(List<E> elements) {
474        return ExplicitOrderedImmutableSortedSet.create(elements);
475      }
476    
477      /**
478       * Returns an immutable sorted set containing the provided elements in the
479       * same order. It is useful when the elements already have the desired order
480       * but constructing the appropriate comparator is difficult.
481       *
482       * @param firstElement the value which should appear first in the generated
483       *     set
484       * @param remainingElementsInOrder the rest of the values in the generated
485       *     set, in the order they should appear
486       * @throws NullPointerException if any of the elements is null
487       * @throws IllegalArgumentException if any duplicate values (according to
488       *     {@link Object#equals(Object)}) are present among the method arguments
489       * @since 3
490       */
491      @Beta
492      public static <E> ImmutableSortedSet<E> withExplicitOrder(
493          E firstElement, E... remainingElementsInOrder) {
494        return withExplicitOrder(
495            Lists.asList(firstElement, remainingElementsInOrder));
496      }
497    
498      /**
499       * Returns a builder that creates immutable sorted sets with an explicit
500       * comparator. If the comparator has a more general type than the set being
501       * generated, such as creating a {@code SortedSet<Integer>} with a
502       * {@code Comparator<Number>}, use the {@link Builder} constructor instead.
503       *
504       * @throws NullPointerException if {@code comparator} is null
505       */
506      public static <E> Builder<E> orderedBy(Comparator<E> comparator) {
507        return new Builder<E>(comparator);
508      }
509    
510      /**
511       * Returns a builder that creates immutable sorted sets whose elements are
512       * ordered by the reverse of their natural ordering.
513       *
514       * <p>Note: the type parameter {@code E} extends {@code Comparable<E>} rather
515       * than {@code Comparable<? super E>} as a workaround for javac <a
516       * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6468354">bug
517       * 6468354</a>.
518       */
519      public static <E extends Comparable<E>> Builder<E> reverseOrder() {
520        return new Builder<E>(Ordering.natural().reverse());
521      }
522    
523      /**
524       * Returns a builder that creates immutable sorted sets whose elements are
525       * ordered by their natural ordering. The sorted sets use {@link
526       * Ordering#natural()} as the comparator. This method provides more
527       * type-safety than {@link #builder}, as it can be called only for classes
528       * that implement {@link Comparable}.
529       *
530       * <p>Note: the type parameter {@code E} extends {@code Comparable<E>} rather
531       * than {@code Comparable<? super E>} as a workaround for javac <a
532       * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6468354">bug
533       * 6468354</a>.
534       */
535      public static <E extends Comparable<E>> Builder<E> naturalOrder() {
536        return new Builder<E>(Ordering.natural());
537      }
538    
539      /**
540       * A builder for creating immutable sorted set instances, especially
541       * {@code public static final} sets ("constant sets"), with a given
542       * comparator.
543       *
544       * <p>Example:
545       * <pre>{@code
546       *   public static final ImmutableSortedSet<Number> LUCKY_NUMBERS
547       *       = new ImmutableSortedSet.Builder<Number>(ODDS_FIRST_COMPARATOR)
548       *           .addAll(SINGLE_DIGIT_PRIMES)
549       *           .add(42)
550       *           .build();}</pre>
551       *
552       * <p>Builder instances can be reused - it is safe to call {@link #build}
553       * multiple times to build multiple sets in series. Each set
554       * is a superset of the set created before it.
555       */
556      public static final class Builder<E> extends ImmutableSet.Builder<E> {
557        private final Comparator<? super E> comparator;
558    
559        /**
560         * Creates a new builder. The returned builder is equivalent to the builder
561         * generated by {@link ImmutableSortedSet#orderedBy}.
562         */
563        public Builder(Comparator<? super E> comparator) {
564          this.comparator = checkNotNull(comparator);
565        }
566    
567        /**
568         * Adds {@code element} to the {@code ImmutableSortedSet}.  If the
569         * {@code ImmutableSortedSet} already contains {@code element}, then
570         * {@code add} has no effect. (only the previously added element
571         * is retained).
572         *
573         * @param element the element to add
574         * @return this {@code Builder} object
575         * @throws NullPointerException if {@code element} is null
576         */
577        @Override public Builder<E> add(E element) {
578          super.add(element);
579          return this;
580        }
581    
582        /**
583         * Adds each element of {@code elements} to the {@code ImmutableSortedSet},
584         * ignoring duplicate elements (only the first duplicate element is added).
585         *
586         * @param elements the elements to add
587         * @return this {@code Builder} object
588         * @throws NullPointerException if {@code elements} contains a null element
589         */
590        @Override public Builder<E> add(E... elements) {
591          super.add(elements);
592          return this;
593        }
594    
595        /**
596         * Adds each element of {@code elements} to the {@code ImmutableSortedSet},
597         * ignoring duplicate elements (only the first duplicate element is added).
598         *
599         * @param elements the elements to add to the {@code ImmutableSortedSet}
600         * @return this {@code Builder} object
601         * @throws NullPointerException if {@code elements} contains a null element
602         */
603        @Override public Builder<E> addAll(Iterable<? extends E> elements) {
604          super.addAll(elements);
605          return this;
606        }
607    
608        /**
609         * Adds each element of {@code elements} to the {@code ImmutableSortedSet},
610         * ignoring duplicate elements (only the first duplicate element is added).
611         *
612         * @param elements the elements to add to the {@code ImmutableSortedSet}
613         * @return this {@code Builder} object
614         * @throws NullPointerException if {@code elements} contains a null element
615         */
616        @Override public Builder<E> addAll(Iterator<? extends E> elements) {
617          super.addAll(elements);
618          return this;
619        }
620    
621        /**
622         * Returns a newly-created {@code ImmutableSortedSet} based on the contents
623         * of the {@code Builder} and its comparator.
624         */
625        @Override public ImmutableSortedSet<E> build() {
626          return copyOfInternal(comparator, contents.iterator());
627        }
628      }
629    
630      int unsafeCompare(Object a, Object b) {
631        return unsafeCompare(comparator, a, b);
632      }
633    
634      static int unsafeCompare(
635          Comparator<?> comparator, Object a, Object b) {
636        // Pretend the comparator can compare anything. If it turns out it can't
637        // compare a and b, we should get a CCE on the subsequent line. Only methods
638        // that are spec'd to throw CCE should call this.
639        @SuppressWarnings("unchecked")
640        Comparator<Object> unsafeComparator = (Comparator<Object>) comparator;
641        return unsafeComparator.compare(a, b);
642      }
643    
644      final transient Comparator<? super E> comparator;
645    
646      ImmutableSortedSet(Comparator<? super E> comparator) {
647        this.comparator = comparator;
648      }
649    
650      /**
651       * Returns the comparator that orders the elements, which is
652       * {@link Ordering#natural()} when the natural ordering of the
653       * elements is used. Note that its behavior is not consistent with
654       * {@link SortedSet#comparator()}, which returns {@code null} to indicate
655       * natural ordering.
656       */
657      public Comparator<? super E> comparator() {
658        return comparator;
659      }
660    
661      /**
662       * {@inheritDoc}
663       *
664       * <p>This method returns a serializable {@code ImmutableSortedSet}.
665       *
666       * <p>The {@link SortedSet#headSet} documentation states that a subset of a
667       * subset throws an {@link IllegalArgumentException} if passed a
668       * {@code toElement} greater than an earlier {@code toElement}. However, this
669       * method doesn't throw an exception in that situation, but instead keeps the
670       * original {@code toElement}.
671       */
672      public ImmutableSortedSet<E> headSet(E toElement) {
673        return headSetImpl(checkNotNull(toElement));
674      }
675    
676      /**
677       * {@inheritDoc}
678       *
679       * <p>This method returns a serializable {@code ImmutableSortedSet}.
680       *
681       * <p>The {@link SortedSet#subSet} documentation states that a subset of a
682       * subset throws an {@link IllegalArgumentException} if passed a
683       * {@code fromElement} smaller than an earlier {@code fromElement}. However,
684       * this method doesn't throw an exception in that situation, but instead keeps
685       * the original {@code fromElement}. Similarly, this method keeps the
686       * original {@code toElement}, instead of throwing an exception, if passed a
687       * {@code toElement} greater than an earlier {@code toElement}.
688       */
689      public ImmutableSortedSet<E> subSet(E fromElement, E toElement) {
690        checkNotNull(fromElement);
691        checkNotNull(toElement);
692        checkArgument(comparator.compare(fromElement, toElement) <= 0);
693        return subSetImpl(fromElement, toElement);
694      }
695    
696      /**
697       * {@inheritDoc}
698       *
699       * <p>This method returns a serializable {@code ImmutableSortedSet}.
700       *
701       * <p>The {@link SortedSet#tailSet} documentation states that a subset of a
702       * subset throws an {@link IllegalArgumentException} if passed a
703       * {@code fromElement} smaller than an earlier {@code fromElement}. However,
704       * this method doesn't throw an exception in that situation, but instead keeps
705       * the original {@code fromElement}.
706       */
707      public ImmutableSortedSet<E> tailSet(E fromElement) {
708        return tailSetImpl(checkNotNull(fromElement));
709      }
710    
711      /*
712       * These methods perform most headSet, subSet, and tailSet logic, besides
713       * parameter validation.
714       */
715      abstract ImmutableSortedSet<E> headSetImpl(E toElement);
716      abstract ImmutableSortedSet<E> subSetImpl(E fromElement, E toElement);
717      abstract ImmutableSortedSet<E> tailSetImpl(E fromElement);
718    
719      /** Returns whether the elements are stored in a subset of a larger array. */
720      abstract boolean hasPartialArray();
721    
722      /**
723       * Returns the position of an element within the set, or -1 if not present.
724       */
725      abstract int indexOf(Object target);
726    
727      /*
728       * This class is used to serialize all ImmutableSortedSet instances,
729       * regardless of implementation type. It captures their "logical contents"
730       * only. This is necessary to ensure that the existence of a particular
731       * implementation type is an implementation detail.
732       */
733      private static class SerializedForm<E> implements Serializable {
734        final Comparator<? super E> comparator;
735        final Object[] elements;
736    
737        public SerializedForm(Comparator<? super E> comparator, Object[] elements) {
738          this.comparator = comparator;
739          this.elements = elements;
740        }
741    
742        @SuppressWarnings("unchecked")
743        Object readResolve() {
744          return new Builder<E>(comparator).add((E[]) elements).build();
745        }
746    
747        private static final long serialVersionUID = 0;
748      }
749    
750      private void readObject(ObjectInputStream stream)
751          throws InvalidObjectException {
752        throw new InvalidObjectException("Use SerializedForm");
753      }
754    
755      @Override Object writeReplace() {
756        return new SerializedForm<E>(comparator, toArray());
757      }
758    }