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