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 017package com.google.common.collect; 018 019import static com.google.common.base.Preconditions.checkNotNull; 020 021import com.google.common.annotations.Beta; 022import com.google.common.annotations.GwtCompatible; 023import com.google.common.base.Equivalence; 024import com.google.common.base.Function; 025import com.google.common.base.Predicate; 026 027import java.io.Serializable; 028import java.util.Collections; 029import java.util.Comparator; 030import java.util.Iterator; 031import java.util.NoSuchElementException; 032import java.util.Set; 033import java.util.SortedSet; 034 035import javax.annotation.Nullable; 036 037/** 038 * A range (or "interval") defines the <i>boundaries</i> around a contiguous span of values of some 039 * {@code Comparable} type; for example, "integers from 1 to 100 inclusive." Note that it is not 040 * possible to <i>iterate</i> over these contained values. To do so, pass this range instance and 041 * an appropriate {@link DiscreteDomain} to {@link ContiguousSet#create}. 042 * 043 * <h3>Types of ranges</h3> 044 * 045 * <p>Each end of the range may be bounded or unbounded. If bounded, there is an associated 046 * <i>endpoint</i> value, and the range is considered to be either <i>open</i> (does not include the 047 * endpoint) or <i>closed</i> (includes the endpoint) on that side. With three possibilities on each 048 * side, this yields nine basic types of ranges, enumerated below. (Notation: a square bracket 049 * ({@code [ ]}) indicates that the range is closed on that side; a parenthesis ({@code ( )}) means 050 * it is either open or unbounded. The construct {@code {x | statement}} is read "the set of all 051 * <i>x</i> such that <i>statement</i>.") 052 * 053 * <blockquote><table> 054 * <tr><td><b>Notation</b> <td><b>Definition</b> <td><b>Factory method</b> 055 * <tr><td>{@code (a..b)} <td>{@code {x | a < x < b}} <td>{@link Range#open open} 056 * <tr><td>{@code [a..b]} <td>{@code {x | a <= x <= b}}<td>{@link Range#closed closed} 057 * <tr><td>{@code (a..b]} <td>{@code {x | a < x <= b}} <td>{@link Range#openClosed openClosed} 058 * <tr><td>{@code [a..b)} <td>{@code {x | a <= x < b}} <td>{@link Range#closedOpen closedOpen} 059 * <tr><td>{@code (a..+∞)} <td>{@code {x | x > a}} <td>{@link Range#greaterThan greaterThan} 060 * <tr><td>{@code [a..+∞)} <td>{@code {x | x >= a}} <td>{@link Range#atLeast atLeast} 061 * <tr><td>{@code (-∞..b)} <td>{@code {x | x < b}} <td>{@link Range#lessThan lessThan} 062 * <tr><td>{@code (-∞..b]} <td>{@code {x | x <= b}} <td>{@link Range#atMost atMost} 063 * <tr><td>{@code (-∞..+∞)}<td>{@code {x}} <td>{@link Range#all all} 064 * </table></blockquote> 065 * 066 * <p>When both endpoints exist, the upper endpoint may not be less than the lower. The endpoints 067 * may be equal only if at least one of the bounds is closed: 068 * 069 * <ul> 070 * <li>{@code [a..a]} : a singleton range 071 * <li>{@code [a..a); (a..a]} : {@linkplain #isEmpty empty} ranges; also valid 072 * <li>{@code (a..a)} : <b>invalid</b>; an exception will be thrown 073 * </ul> 074 * 075 * <h3>Warnings</h3> 076 * 077 * <ul> 078 * <li>Use immutable value types only, if at all possible. If you must use a mutable type, <b>do 079 * not</b> allow the endpoint instances to mutate after the range is created! 080 * <li>Your value type's comparison method should be {@linkplain Comparable consistent with equals} 081 * if at all possible. Otherwise, be aware that concepts used throughout this documentation such 082 * as "equal", "same", "unique" and so on actually refer to whether {@link Comparable#compareTo 083 * compareTo} returns zero, not whether {@link Object#equals equals} returns {@code true}. 084 * <li>A class which implements {@code Comparable<UnrelatedType>} is very broken, and will cause 085 * undefined horrible things to happen in {@code Range}. For now, the Range API does not prevent 086 * its use, because this would also rule out all ungenerified (pre-JDK1.5) data types. <b>This 087 * may change in the future.</b> 088 * </ul> 089 * 090 * <h3>Other notes</h3> 091 * 092 * <ul> 093 * <li>Instances of this type are obtained using the static factory methods in this class. 094 * <li>Ranges are <i>convex</i>: whenever two values are contained, all values in between them must 095 * also be contained. More formally, for any {@code c1 <= c2 <= c3} of type {@code C}, {@code 096 * r.contains(c1) && r.contains(c3)} implies {@code r.contains(c2)}). This means that a {@code 097 * Range<Integer>} can never be used to represent, say, "all <i>prime</i> numbers from 1 to 098 * 100." 099 * <li>When evaluated as a {@link Predicate}, a range yields the same result as invoking {@link 100 * #contains}. 101 * <li>Terminology note: a range {@code a} is said to be the <i>maximal</i> range having property 102 * <i>P</i> if, for all ranges {@code b} also having property <i>P</i>, {@code a.encloses(b)}. 103 * Likewise, {@code a} is <i>minimal</i> when {@code b.encloses(a)} for all {@code b} having 104 * property <i>P</i>. See, for example, the definition of {@link #intersection intersection}. 105 * </ul> 106 * 107 * <h3>Further reading</h3> 108 * 109 * <p>See the Guava User Guide article on 110 * <a href="http://code.google.com/p/guava-libraries/wiki/RangesExplained">{@code Range}</a>. 111 * 112 * @author Kevin Bourrillion 113 * @author Gregory Kick 114 * @since 10.0 115 */ 116@GwtCompatible 117@SuppressWarnings("rawtypes") 118public final class Range<C extends Comparable> implements Predicate<C>, Serializable { 119 120 private static final Function<Range, Cut> LOWER_BOUND_FN = new Function<Range, Cut>() { 121 @Override 122 public Cut apply(Range range) { 123 return range.lowerBound; 124 } 125 }; 126 127 @SuppressWarnings("unchecked") 128 static <C extends Comparable<?>> Function<Range<C>, Cut<C>> lowerBoundFn() { 129 return (Function) LOWER_BOUND_FN; 130 } 131 132 private static final Function<Range, Cut> UPPER_BOUND_FN = new Function<Range, Cut>() { 133 @Override 134 public Cut apply(Range range) { 135 return range.upperBound; 136 } 137 }; 138 139 @SuppressWarnings("unchecked") 140 static <C extends Comparable<?>> Function<Range<C>, Cut<C>> upperBoundFn() { 141 return (Function) UPPER_BOUND_FN; 142 } 143 144 static final Ordering<Range<?>> RANGE_LEX_ORDERING = new Ordering<Range<?>>() { 145 @Override 146 public int compare(Range<?> left, Range<?> right) { 147 return ComparisonChain.start() 148 .compare(left.lowerBound, right.lowerBound) 149 .compare(left.upperBound, right.upperBound) 150 .result(); 151 } 152 }; 153 154 static <C extends Comparable<?>> Range<C> create( 155 Cut<C> lowerBound, Cut<C> upperBound) { 156 return new Range<C>(lowerBound, upperBound); 157 } 158 159 /** 160 * Returns a range that contains all values strictly greater than {@code 161 * lower} and strictly less than {@code upper}. 162 * 163 * @throws IllegalArgumentException if {@code lower} is greater than <i>or 164 * equal to</i> {@code upper} 165 * @since 14.0 166 */ 167 public static <C extends Comparable<?>> Range<C> open(C lower, C upper) { 168 return create(Cut.aboveValue(lower), Cut.belowValue(upper)); 169 } 170 171 /** 172 * Returns a range that contains all values greater than or equal to 173 * {@code lower} and less than or equal to {@code upper}. 174 * 175 * @throws IllegalArgumentException if {@code lower} is greater than {@code 176 * upper} 177 * @since 14.0 178 */ 179 public static <C extends Comparable<?>> Range<C> closed(C lower, C upper) { 180 return create(Cut.belowValue(lower), Cut.aboveValue(upper)); 181 } 182 183 /** 184 * Returns a range that contains all values greater than or equal to 185 * {@code lower} and strictly less than {@code upper}. 186 * 187 * @throws IllegalArgumentException if {@code lower} is greater than {@code 188 * upper} 189 * @since 14.0 190 */ 191 public static <C extends Comparable<?>> Range<C> closedOpen( 192 C lower, C upper) { 193 return create(Cut.belowValue(lower), Cut.belowValue(upper)); 194 } 195 196 /** 197 * Returns a range that contains all values strictly greater than {@code 198 * lower} and less than or equal to {@code upper}. 199 * 200 * @throws IllegalArgumentException if {@code lower} is greater than {@code 201 * upper} 202 * @since 14.0 203 */ 204 public static <C extends Comparable<?>> Range<C> openClosed( 205 C lower, C upper) { 206 return create(Cut.aboveValue(lower), Cut.aboveValue(upper)); 207 } 208 209 /** 210 * Returns a range that contains any value from {@code lower} to {@code 211 * upper}, where each endpoint may be either inclusive (closed) or exclusive 212 * (open). 213 * 214 * @throws IllegalArgumentException if {@code lower} is greater than {@code 215 * upper} 216 * @since 14.0 217 */ 218 public static <C extends Comparable<?>> Range<C> range( 219 C lower, BoundType lowerType, C upper, BoundType upperType) { 220 checkNotNull(lowerType); 221 checkNotNull(upperType); 222 223 Cut<C> lowerBound = (lowerType == BoundType.OPEN) 224 ? Cut.aboveValue(lower) 225 : Cut.belowValue(lower); 226 Cut<C> upperBound = (upperType == BoundType.OPEN) 227 ? Cut.belowValue(upper) 228 : Cut.aboveValue(upper); 229 return create(lowerBound, upperBound); 230 } 231 232 /** 233 * Returns a range that contains all values strictly less than {@code 234 * endpoint}. 235 * 236 * @since 14.0 237 */ 238 public static <C extends Comparable<?>> Range<C> lessThan(C endpoint) { 239 return create(Cut.<C>belowAll(), Cut.belowValue(endpoint)); 240 } 241 242 /** 243 * Returns a range that contains all values less than or equal to 244 * {@code endpoint}. 245 * 246 * @since 14.0 247 */ 248 public static <C extends Comparable<?>> Range<C> atMost(C endpoint) { 249 return create(Cut.<C>belowAll(), Cut.aboveValue(endpoint)); 250 } 251 252 /** 253 * Returns a range with no lower bound up to the given endpoint, which may be 254 * either inclusive (closed) or exclusive (open). 255 * 256 * @since 14.0 257 */ 258 public static <C extends Comparable<?>> Range<C> upTo( 259 C endpoint, BoundType boundType) { 260 switch (boundType) { 261 case OPEN: 262 return lessThan(endpoint); 263 case CLOSED: 264 return atMost(endpoint); 265 default: 266 throw new AssertionError(); 267 } 268 } 269 270 /** 271 * Returns a range that contains all values strictly greater than {@code 272 * endpoint}. 273 * 274 * @since 14.0 275 */ 276 public static <C extends Comparable<?>> Range<C> greaterThan(C endpoint) { 277 return create(Cut.aboveValue(endpoint), Cut.<C>aboveAll()); 278 } 279 280 /** 281 * Returns a range that contains all values greater than or equal to 282 * {@code endpoint}. 283 * 284 * @since 14.0 285 */ 286 public static <C extends Comparable<?>> Range<C> atLeast(C endpoint) { 287 return create(Cut.belowValue(endpoint), Cut.<C>aboveAll()); 288 } 289 290 /** 291 * Returns a range from the given endpoint, which may be either inclusive 292 * (closed) or exclusive (open), with no upper bound. 293 * 294 * @since 14.0 295 */ 296 public static <C extends Comparable<?>> Range<C> downTo( 297 C endpoint, BoundType boundType) { 298 switch (boundType) { 299 case OPEN: 300 return greaterThan(endpoint); 301 case CLOSED: 302 return atLeast(endpoint); 303 default: 304 throw new AssertionError(); 305 } 306 } 307 308 private static final Range<Comparable> ALL = 309 new Range<Comparable>(Cut.belowAll(), Cut.aboveAll()); 310 311 /** 312 * Returns a range that contains every value of type {@code C}. 313 * 314 * @since 14.0 315 */ 316 @SuppressWarnings("unchecked") 317 public static <C extends Comparable<?>> Range<C> all() { 318 return (Range) ALL; 319 } 320 321 /** 322 * Returns a range that {@linkplain Range#contains(Comparable) contains} only 323 * the given value. The returned range is {@linkplain BoundType#CLOSED closed} 324 * on both ends. 325 * 326 * @since 14.0 327 */ 328 public static <C extends Comparable<?>> Range<C> singleton(C value) { 329 return closed(value, value); 330 } 331 332 /** 333 * Returns the minimal range that 334 * {@linkplain Range#contains(Comparable) contains} all of the given values. 335 * The returned range is {@linkplain BoundType#CLOSED closed} on both ends. 336 * 337 * @throws ClassCastException if the parameters are not <i>mutually 338 * comparable</i> 339 * @throws NoSuchElementException if {@code values} is empty 340 * @throws NullPointerException if any of {@code values} is null 341 * @since 14.0 342 */ 343 public static <C extends Comparable<?>> Range<C> encloseAll( 344 Iterable<C> values) { 345 checkNotNull(values); 346 if (values instanceof ContiguousSet) { 347 return ((ContiguousSet<C>) values).range(); 348 } 349 Iterator<C> valueIterator = values.iterator(); 350 C min = checkNotNull(valueIterator.next()); 351 C max = min; 352 while (valueIterator.hasNext()) { 353 C value = checkNotNull(valueIterator.next()); 354 min = Ordering.natural().min(min, value); 355 max = Ordering.natural().max(max, value); 356 } 357 return closed(min, max); 358 } 359 360 final Cut<C> lowerBound; 361 final Cut<C> upperBound; 362 363 private Range(Cut<C> lowerBound, Cut<C> upperBound) { 364 if (lowerBound.compareTo(upperBound) > 0 || lowerBound == Cut.<C>aboveAll() 365 || upperBound == Cut.<C>belowAll()) { 366 throw new IllegalArgumentException("Invalid range: " + toString(lowerBound, upperBound)); 367 } 368 this.lowerBound = checkNotNull(lowerBound); 369 this.upperBound = checkNotNull(upperBound); 370 } 371 372 /** 373 * Returns {@code true} if this range has a lower endpoint. 374 */ 375 public boolean hasLowerBound() { 376 return lowerBound != Cut.belowAll(); 377 } 378 379 /** 380 * Returns the lower endpoint of this range. 381 * 382 * @throws IllegalStateException if this range is unbounded below (that is, {@link 383 * #hasLowerBound()} returns {@code false}) 384 */ 385 public C lowerEndpoint() { 386 return lowerBound.endpoint(); 387 } 388 389 /** 390 * Returns the type of this range's lower bound: {@link BoundType#CLOSED} if the range includes 391 * its lower endpoint, {@link BoundType#OPEN} if it does not. 392 * 393 * @throws IllegalStateException if this range is unbounded below (that is, {@link 394 * #hasLowerBound()} returns {@code false}) 395 */ 396 public BoundType lowerBoundType() { 397 return lowerBound.typeAsLowerBound(); 398 } 399 400 /** 401 * Returns {@code true} if this range has an upper endpoint. 402 */ 403 public boolean hasUpperBound() { 404 return upperBound != Cut.aboveAll(); 405 } 406 407 /** 408 * Returns the upper endpoint of this range. 409 * 410 * @throws IllegalStateException if this range is unbounded above (that is, {@link 411 * #hasUpperBound()} returns {@code false}) 412 */ 413 public C upperEndpoint() { 414 return upperBound.endpoint(); 415 } 416 417 /** 418 * Returns the type of this range's upper bound: {@link BoundType#CLOSED} if the range includes 419 * its upper endpoint, {@link BoundType#OPEN} if it does not. 420 * 421 * @throws IllegalStateException if this range is unbounded above (that is, {@link 422 * #hasUpperBound()} returns {@code false}) 423 */ 424 public BoundType upperBoundType() { 425 return upperBound.typeAsUpperBound(); 426 } 427 428 /** 429 * Returns {@code true} if this range is of the form {@code [v..v)} or {@code (v..v]}. (This does 430 * not encompass ranges of the form {@code (v..v)}, because such ranges are <i>invalid</i> and 431 * can't be constructed at all.) 432 * 433 * <p>Note that certain discrete ranges such as the integer range {@code (3..4)} are <b>not</b> 434 * considered empty, even though they contain no actual values. In these cases, it may be 435 * helpful to preprocess ranges with {@link #canonical(DiscreteDomain)}. 436 */ 437 public boolean isEmpty() { 438 return lowerBound.equals(upperBound); 439 } 440 441 /** 442 * Returns {@code true} if {@code value} is within the bounds of this range. For example, on the 443 * range {@code [0..2)}, {@code contains(1)} returns {@code true}, while {@code contains(2)} 444 * returns {@code false}. 445 */ 446 public boolean contains(C value) { 447 checkNotNull(value); 448 // let this throw CCE if there is some trickery going on 449 return lowerBound.isLessThan(value) && !upperBound.isLessThan(value); 450 } 451 452 /** 453 * Equivalent to {@link #contains}; provided only to satisfy the {@link Predicate} interface. When 454 * using a reference of type {@code Range}, always invoke {@link #contains} directly instead. 455 */ 456 @Override public boolean apply(C input) { 457 return contains(input); 458 } 459 460 /** 461 * Returns {@code true} if every element in {@code values} is {@linkplain #contains contained} in 462 * this range. 463 */ 464 public boolean containsAll(Iterable<? extends C> values) { 465 if (Iterables.isEmpty(values)) { 466 return true; 467 } 468 469 // this optimizes testing equality of two range-backed sets 470 if (values instanceof SortedSet) { 471 SortedSet<? extends C> set = cast(values); 472 Comparator<?> comparator = set.comparator(); 473 if (Ordering.natural().equals(comparator) || comparator == null) { 474 return contains(set.first()) && contains(set.last()); 475 } 476 } 477 478 for (C value : values) { 479 if (!contains(value)) { 480 return false; 481 } 482 } 483 return true; 484 } 485 486 /** 487 * Returns {@code true} if the bounds of {@code other} do not extend outside the bounds of this 488 * range. Examples: 489 * 490 * <ul> 491 * <li>{@code [3..6]} encloses {@code [4..5]} 492 * <li>{@code (3..6)} encloses {@code (3..6)} 493 * <li>{@code [3..6]} encloses {@code [4..4)} (even though the latter is empty) 494 * <li>{@code (3..6]} does not enclose {@code [3..6]} 495 * <li>{@code [4..5]} does not enclose {@code (3..6)} (even though it contains every value 496 * contained by the latter range) 497 * <li>{@code [3..6]} does not enclose {@code (1..1]} (even though it contains every value 498 * contained by the latter range) 499 * </ul> 500 * 501 * <p>Note that if {@code a.encloses(b)}, then {@code b.contains(v)} implies 502 * {@code a.contains(v)}, but as the last two examples illustrate, the converse is not always 503 * true. 504 * 505 * <p>Being reflexive, antisymmetric and transitive, the {@code encloses} relation defines a 506 * <i>partial order</i> over ranges. There exists a unique {@linkplain Range#all maximal} range 507 * according to this relation, and also numerous {@linkplain #isEmpty minimal} ranges. Enclosure 508 * also implies {@linkplain #isConnected connectedness}. 509 */ 510 public boolean encloses(Range<C> other) { 511 return lowerBound.compareTo(other.lowerBound) <= 0 512 && upperBound.compareTo(other.upperBound) >= 0; 513 } 514 515 /** 516 * Returns {@code true} if there exists a (possibly empty) range which is {@linkplain #encloses 517 * enclosed} by both this range and {@code other}. 518 * 519 * <p>For example, 520 * <ul> 521 * <li>{@code [2, 4)} and {@code [5, 7)} are not connected 522 * <li>{@code [2, 4)} and {@code [3, 5)} are connected, because both enclose {@code [3, 4)} 523 * <li>{@code [2, 4)} and {@code [4, 6)} are connected, because both enclose the empty range 524 * {@code [4, 4)} 525 * </ul> 526 * 527 * <p>Note that this range and {@code other} have a well-defined {@linkplain #span union} and 528 * {@linkplain #intersection intersection} (as a single, possibly-empty range) if and only if this 529 * method returns {@code true}. 530 * 531 * <p>The connectedness relation is both reflexive and symmetric, but does not form an {@linkplain 532 * Equivalence equivalence relation} as it is not transitive. 533 * 534 * <p>Note that certain discrete ranges are not considered connected, even though there are no 535 * elements "between them." For example, {@code [3, 5]} is not considered connected to {@code 536 * [6, 10]}. In these cases, it may be desirable for both input ranges to be preprocessed with 537 * {@link #canonical(DiscreteDomain)} before testing for connectedness. 538 */ 539 public boolean isConnected(Range<C> other) { 540 return lowerBound.compareTo(other.upperBound) <= 0 541 && other.lowerBound.compareTo(upperBound) <= 0; 542 } 543 544 /** 545 * Returns the maximal range {@linkplain #encloses enclosed} by both this range and {@code 546 * connectedRange}, if such a range exists. 547 * 548 * <p>For example, the intersection of {@code [1..5]} and {@code (3..7)} is {@code (3..5]}. The 549 * resulting range may be empty; for example, {@code [1..5)} intersected with {@code [5..7)} 550 * yields the empty range {@code [5..5)}. 551 * 552 * <p>The intersection exists if and only if the two ranges are {@linkplain #isConnected 553 * connected}. 554 * 555 * <p>The intersection operation is commutative, associative and idempotent, and its identity 556 * element is {@link Range#all}). 557 * 558 * @throws IllegalArgumentException if {@code isConnected(connectedRange)} is {@code false} 559 */ 560 public Range<C> intersection(Range<C> connectedRange) { 561 int lowerCmp = lowerBound.compareTo(connectedRange.lowerBound); 562 int upperCmp = upperBound.compareTo(connectedRange.upperBound); 563 if (lowerCmp >= 0 && upperCmp <= 0) { 564 return this; 565 } else if (lowerCmp <= 0 && upperCmp >= 0) { 566 return connectedRange; 567 } else { 568 Cut<C> newLower = (lowerCmp >= 0) ? lowerBound : connectedRange.lowerBound; 569 Cut<C> newUpper = (upperCmp <= 0) ? upperBound : connectedRange.upperBound; 570 return create(newLower, newUpper); 571 } 572 } 573 574 /** 575 * Returns the minimal range that {@linkplain #encloses encloses} both this range and {@code 576 * other}. For example, the span of {@code [1..3]} and {@code (5..7)} is {@code [1..7)}. 577 * 578 * <p><i>If</i> the input ranges are {@linkplain #isConnected connected}, the returned range can 579 * also be called their <i>union</i>. If they are not, note that the span might contain values 580 * that are not contained in either input range. 581 * 582 * <p>Like {@link #intersection(Range) intersection}, this operation is commutative, associative 583 * and idempotent. Unlike it, it is always well-defined for any two input ranges. 584 */ 585 public Range<C> span(Range<C> other) { 586 int lowerCmp = lowerBound.compareTo(other.lowerBound); 587 int upperCmp = upperBound.compareTo(other.upperBound); 588 if (lowerCmp <= 0 && upperCmp >= 0) { 589 return this; 590 } else if (lowerCmp >= 0 && upperCmp <= 0) { 591 return other; 592 } else { 593 Cut<C> newLower = (lowerCmp <= 0) ? lowerBound : other.lowerBound; 594 Cut<C> newUpper = (upperCmp >= 0) ? upperBound : other.upperBound; 595 return create(newLower, newUpper); 596 } 597 } 598 599 /** 600 * Returns an {@link ContiguousSet} containing the same values in the given domain 601 * {@linkplain Range#contains contained} by this range. 602 * 603 * <p><b>Note:</b> {@code a.asSet(d).equals(b.asSet(d))} does not imply {@code a.equals(b)}! For 604 * example, {@code a} and {@code b} could be {@code [2..4]} and {@code (1..5)}, or the empty 605 * ranges {@code [3..3)} and {@code [4..4)}. 606 * 607 * <p><b>Warning:</b> Be extremely careful what you do with the {@code asSet} view of a large 608 * range (such as {@code Range.greaterThan(0)}). Certain operations on such a set can be 609 * performed efficiently, but others (such as {@link Set#hashCode} or {@link 610 * Collections#frequency}) can cause major performance problems. 611 * 612 * <p>The returned set's {@link Object#toString} method returns a short-hand form of the set's 613 * contents, such as {@code "[1..100]}"}. 614 * 615 * @throws IllegalArgumentException if neither this range nor the domain has a lower bound, or if 616 * neither has an upper bound 617 * @deprecated Use {@code ContiguousSet.create(range, domain)}. To be removed in Guava 16.0. 618 */ 619 @Beta 620 @GwtCompatible(serializable = false) 621 @Deprecated 622 public ContiguousSet<C> asSet(DiscreteDomain<C> domain) { 623 return ContiguousSet.create(this, domain); 624 } 625 626 /** 627 * Returns the canonical form of this range in the given domain. The canonical form has the 628 * following properties: 629 * 630 * <ul> 631 * <li>equivalence: {@code a.canonical().contains(v) == a.contains(v)} for all {@code v} (in other 632 * words, {@code ContiguousSet.create(a.canonical(domain), domain).equals( 633 * ContiguousSet.create(a, domain))} 634 * <li>uniqueness: unless {@code a.isEmpty()}, 635 * {@code ContiguousSet.create(a, domain).equals(ContiguousSet.create(b, domain))} implies 636 * {@code a.canonical(domain).equals(b.canonical(domain))} 637 * <li>idempotence: {@code a.canonical(domain).canonical(domain).equals(a.canonical(domain))} 638 * </ul> 639 * 640 * <p>Furthermore, this method guarantees that the range returned will be one of the following 641 * canonical forms: 642 * 643 * <ul> 644 * <li>[start..end) 645 * <li>[start..+∞) 646 * <li>(-∞..end) (only if type {@code C} is unbounded below) 647 * <li>(-∞..+∞) (only if type {@code C} is unbounded below) 648 * </ul> 649 */ 650 public Range<C> canonical(DiscreteDomain<C> domain) { 651 checkNotNull(domain); 652 Cut<C> lower = lowerBound.canonical(domain); 653 Cut<C> upper = upperBound.canonical(domain); 654 return (lower == lowerBound && upper == upperBound) ? this : create(lower, upper); 655 } 656 657 /** 658 * Returns {@code true} if {@code object} is a range having the same endpoints and bound types as 659 * this range. Note that discrete ranges such as {@code (1..4)} and {@code [2..3]} are <b>not</b> 660 * equal to one another, despite the fact that they each contain precisely the same set of values. 661 * Similarly, empty ranges are not equal unless they have exactly the same representation, so 662 * {@code [3..3)}, {@code (3..3]}, {@code (4..4]} are all unequal. 663 */ 664 @Override public boolean equals(@Nullable Object object) { 665 if (object instanceof Range) { 666 Range<?> other = (Range<?>) object; 667 return lowerBound.equals(other.lowerBound) 668 && upperBound.equals(other.upperBound); 669 } 670 return false; 671 } 672 673 /** Returns a hash code for this range. */ 674 @Override public int hashCode() { 675 return lowerBound.hashCode() * 31 + upperBound.hashCode(); 676 } 677 678 /** 679 * Returns a string representation of this range, such as {@code "[3..5)"} (other examples are 680 * listed in the class documentation). 681 */ 682 @Override public String toString() { 683 return toString(lowerBound, upperBound); 684 } 685 686 private static String toString(Cut<?> lowerBound, Cut<?> upperBound) { 687 StringBuilder sb = new StringBuilder(16); 688 lowerBound.describeAsLowerBound(sb); 689 sb.append('\u2025'); 690 upperBound.describeAsUpperBound(sb); 691 return sb.toString(); 692 } 693 694 /** 695 * Used to avoid http://bugs.sun.com/view_bug.do?bug_id=6558557 696 */ 697 private static <T> SortedSet<T> cast(Iterable<T> iterable) { 698 return (SortedSet<T>) iterable; 699 } 700 701 Object readResolve() { 702 if (this.equals(ALL)) { 703 return all(); 704 } else { 705 return this; 706 } 707 } 708 709 @SuppressWarnings("unchecked") // this method may throw CCE 710 static int compareOrThrow(Comparable left, Comparable right) { 711 return left.compareTo(right); 712 } 713 714 private static final long serialVersionUID = 0; 715}