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