Class Range<C extends Comparable>

  • All Implemented Interfaces:
    Predicate<C>, Serializable, Predicate<C>

    @GwtCompatible
    public final class Range<C extends Comparable>
    extends Object
    implements Predicate<C>, Serializable
    A range (or "interval") defines the boundaries around a contiguous span of values of some Comparable type; for example, "integers from 1 to 100 inclusive." Note that it is not possible to iterate over these contained values. To do so, pass this range instance and an appropriate DiscreteDomain to ContiguousSet.create(com.google.common.collect.Range<C>, com.google.common.collect.DiscreteDomain<C>).

    Types of ranges

    Each end of the range may be bounded or unbounded. If bounded, there is an associated endpoint value, and the range is considered to be either open (does not include the endpoint) or closed (includes the endpoint) on that side. With three possibilities on each side, this yields nine basic types of ranges, enumerated below. (Notation: a square bracket ([ ]) indicates that the range is closed on that side; a parenthesis (( )) means it is either open or unbounded. The construct {x | statement} is read "the set of all x such that statement.")

    Range Types
    Notation Definition Factory method
    (a..b) {x | a < x < b} open
    [a..b] {x | a <= x <= b}closed
    (a..b] {x | a < x <= b} openClosed
    [a..b) {x | a <= x < b} closedOpen
    (a..+∞) {x | x > a} greaterThan
    [a..+∞) {x | x >= a} atLeast
    (-∞..b) {x | x < b} lessThan
    (-∞..b] {x | x <= b} atMost
    (-∞..+∞){x} all

    When both endpoints exist, the upper endpoint may not be less than the lower. The endpoints may be equal only if at least one of the bounds is closed:

    • [a..a] : a singleton range
    • [a..a); (a..a] : empty ranges; also valid
    • (a..a) : invalid; an exception will be thrown

    Warnings

    • Use immutable value types only, if at all possible. If you must use a mutable type, do not allow the endpoint instances to mutate after the range is created!
    • Your value type's comparison method should be consistent with equals if at all possible. Otherwise, be aware that concepts used throughout this documentation such as "equal", "same", "unique" and so on actually refer to whether compareTo returns zero, not whether equals returns true.
    • A class which implements Comparable<UnrelatedType> is very broken, and will cause undefined horrible things to happen in Range. For now, the Range API does not prevent its use, because this would also rule out all ungenerified (pre-JDK1.5) data types. This may change in the future.

    Other notes

    • All ranges are shallow-immutable.
    • Instances of this type are obtained using the static factory methods in this class.
    • Ranges are convex: whenever two values are contained, all values in between them must also be contained. More formally, for any c1 <= c2 <= c3 of type C, r.contains(c1) && r.contains(c3) implies r.contains(c2)). This means that a Range<Integer> can never be used to represent, say, "all prime numbers from 1 to 100."
    • When evaluated as a Predicate, a range yields the same result as invoking contains(C).
    • Terminology note: a range a is said to be the maximal range having property P if, for all ranges b also having property P, a.encloses(b). Likewise, a is minimal when b.encloses(a) for all b having property P. See, for example, the definition of intersection.

    Further reading

    See the Guava User Guide article on Range.

    Since:
    10.0
    Author:
    Kevin Bourrillion, Gregory Kick
    See Also:
    Serialized Form
    • Method Detail

      • open

        public static <C extends Comparable<?>> Range<C> open(C lower,
                                                              C upper)
        Returns a range that contains all values strictly greater than lower and strictly less than upper.
        Throws:
        IllegalArgumentException - if lower is greater than or equal to upper
        ClassCastException - if lower and upper are not mutually comparable
        Since:
        14.0
      • closed

        public static <C extends Comparable<?>> Range<C> closed(C lower,
                                                                C upper)
        Returns a range that contains all values greater than or equal to lower and less than or equal to upper.
        Throws:
        IllegalArgumentException - if lower is greater than upper
        ClassCastException - if lower and upper are not mutually comparable
        Since:
        14.0
      • closedOpen

        public static <C extends Comparable<?>> Range<C> closedOpen(C lower,
                                                                    C upper)
        Returns a range that contains all values greater than or equal to lower and strictly less than upper.
        Throws:
        IllegalArgumentException - if lower is greater than upper
        ClassCastException - if lower and upper are not mutually comparable
        Since:
        14.0
      • openClosed

        public static <C extends Comparable<?>> Range<C> openClosed(C lower,
                                                                    C upper)
        Returns a range that contains all values strictly greater than lower and less than or equal to upper.
        Throws:
        IllegalArgumentException - if lower is greater than upper
        ClassCastException - if lower and upper are not mutually comparable
        Since:
        14.0
      • range

        public static <C extends Comparable<?>> Range<C> range(C lower,
                                                               BoundType lowerType,
                                                               C upper,
                                                               BoundType upperType)
        Returns a range that contains any value from lower to upper, where each endpoint may be either inclusive (closed) or exclusive (open).
        Throws:
        IllegalArgumentException - if lower is greater than upper
        ClassCastException - if lower and upper are not mutually comparable
        Since:
        14.0
      • lessThan

        public static <C extends Comparable<?>> Range<C> lessThan(C endpoint)
        Returns a range that contains all values strictly less than endpoint.
        Since:
        14.0
      • atMost

        public static <C extends Comparable<?>> Range<C> atMost(C endpoint)
        Returns a range that contains all values less than or equal to endpoint.
        Since:
        14.0
      • upTo

        public static <C extends Comparable<?>> Range<C> upTo(C endpoint,
                                                              BoundType boundType)
        Returns a range with no lower bound up to the given endpoint, which may be either inclusive (closed) or exclusive (open).
        Since:
        14.0
      • greaterThan

        public static <C extends Comparable<?>> Range<C> greaterThan(C endpoint)
        Returns a range that contains all values strictly greater than endpoint.
        Since:
        14.0
      • atLeast

        public static <C extends Comparable<?>> Range<C> atLeast(C endpoint)
        Returns a range that contains all values greater than or equal to endpoint.
        Since:
        14.0
      • downTo

        public static <C extends Comparable<?>> Range<C> downTo(C endpoint,
                                                                BoundType boundType)
        Returns a range from the given endpoint, which may be either inclusive (closed) or exclusive (open), with no upper bound.
        Since:
        14.0
      • all

        public static <C extends Comparable<?>> Range<C> all()
        Returns a range that contains every value of type C.
        Since:
        14.0
      • singleton

        public static <C extends Comparable<?>> Range<C> singleton(C value)
        Returns a range that contains only the given value. The returned range is closed on both ends.
        Since:
        14.0
      • hasLowerBound

        public boolean hasLowerBound()
        Returns true if this range has a lower endpoint.
      • hasUpperBound

        public boolean hasUpperBound()
        Returns true if this range has an upper endpoint.
      • isEmpty

        public boolean isEmpty()
        Returns true if this range is of the form [v..v) or (v..v]. (This does not encompass ranges of the form (v..v), because such ranges are invalid and can't be constructed at all.)

        Note that certain discrete ranges such as the integer range (3..4) are not considered empty, even though they contain no actual values. In these cases, it may be helpful to preprocess ranges with canonical(DiscreteDomain).

      • contains

        public boolean contains(C value)
        Returns true if value is within the bounds of this range. For example, on the range [0..2), contains(1) returns true, while contains(2) returns false.
      • apply

        @Deprecated
        public boolean apply(C input)
        Deprecated.
        Provided only to satisfy the Predicate interface; use contains(C) instead.
        Description copied from interface: Predicate
        Returns the result of applying this predicate to input (Java 8 users, see notes in the class documentation above). This method is generally expected, but not absolutely required, to have the following properties:
        • Its execution does not cause any observable side effects.
        • The computation is consistent with equals; that is, Objects.equal(a, b) implies that predicate.apply(a) == predicate.apply(b)).
        Specified by:
        apply in interface Predicate<C extends Comparable>
      • encloses

        public boolean encloses(Range<C> other)
        Returns true if the bounds of other do not extend outside the bounds of this range. Examples:
        • [3..6] encloses [4..5]
        • (3..6) encloses (3..6)
        • [3..6] encloses [4..4) (even though the latter is empty)
        • (3..6] does not enclose [3..6]
        • [4..5] does not enclose (3..6) (even though it contains every value contained by the latter range)
        • [3..6] does not enclose (1..1] (even though it contains every value contained by the latter range)

        Note that if a.encloses(b), then b.contains(v) implies a.contains(v), but as the last two examples illustrate, the converse is not always true.

        Being reflexive, antisymmetric and transitive, the encloses relation defines a partial order over ranges. There exists a unique maximal range according to this relation, and also numerous minimal ranges. Enclosure also implies connectedness.

      • isConnected

        public boolean isConnected(Range<C> other)
        Returns true if there exists a (possibly empty) range which is enclosed by both this range and other.

        For example,

        • [2, 4) and [5, 7) are not connected
        • [2, 4) and [3, 5) are connected, because both enclose [3, 4)
        • [2, 4) and [4, 6) are connected, because both enclose the empty range [4, 4)

        Note that this range and other have a well-defined union and intersection (as a single, possibly-empty range) if and only if this method returns true.

        The connectedness relation is both reflexive and symmetric, but does not form an equivalence relation as it is not transitive.

        Note that certain discrete ranges are not considered connected, even though there are no elements "between them." For example, [3, 5] is not considered connected to [6, 10]. In these cases, it may be desirable for both input ranges to be preprocessed with canonical(DiscreteDomain) before testing for connectedness.

      • intersection

        public Range<Cintersection(Range<C> connectedRange)
        Returns the maximal range enclosed by both this range and connectedRange, if such a range exists.

        For example, the intersection of [1..5] and (3..7) is (3..5]. The resulting range may be empty; for example, [1..5) intersected with [5..7) yields the empty range [5..5).

        The intersection exists if and only if the two ranges are connected.

        The intersection operation is commutative, associative and idempotent, and its identity element is all()).

        Throws:
        IllegalArgumentException - if isConnected(connectedRange) is false
      • gap

        public Range<Cgap(Range<C> otherRange)
        Returns the maximal range lying between this range and otherRange, if such a range exists. The resulting range may be empty if the two ranges are adjacent but non-overlapping.

        For example, the gap of [1..5] and (7..10) is (5..7]. The resulting range may be empty; for example, the gap between [1..5) [5..7) yields the empty range [5..5).

        The gap exists if and only if the two ranges are either disconnected or immediately adjacent (any intersection must be an empty range).

        The gap operation is commutative.

        Throws:
        IllegalArgumentException - if this range and otherRange have a nonempty intersection
        Since:
        27.0
      • span

        public Range<Cspan(Range<C> other)
        Returns the minimal range that encloses both this range and other. For example, the span of [1..3] and (5..7) is [1..7).

        If the input ranges are connected, the returned range can also be called their union. If they are not, note that the span might contain values that are not contained in either input range.

        Like intersection, this operation is commutative, associative and idempotent. Unlike it, it is always well-defined for any two input ranges.

      • canonical

        public Range<Ccanonical(DiscreteDomain<C> domain)
        Returns the canonical form of this range in the given domain. The canonical form has the following properties:
        • equivalence: a.canonical().contains(v) == a.contains(v) for all v (in other words, ContiguousSet.create(a.canonical(domain), domain).equals( ContiguousSet.create(a, domain))
        • uniqueness: unless a.isEmpty(), ContiguousSet.create(a, domain).equals(ContiguousSet.create(b, domain)) implies a.canonical(domain).equals(b.canonical(domain))
        • idempotence: a.canonical(domain).canonical(domain).equals(a.canonical(domain))

        Furthermore, this method guarantees that the range returned will be one of the following canonical forms:

        • [start..end)
        • [start..+∞)
        • (-∞..end) (only if type C is unbounded below)
        • (-∞..+∞) (only if type C is unbounded below)
      • equals

        public boolean equals(@Nullable Object object)
        Returns true if object is a range having the same endpoints and bound types as this range. Note that discrete ranges such as (1..4) and [2..3] are not equal to one another, despite the fact that they each contain precisely the same set of values. Similarly, empty ranges are not equal unless they have exactly the same representation, so [3..3), (3..3], (4..4] are all unequal.
        Specified by:
        equals in interface Predicate<C extends Comparable>
        Overrides:
        equals in class Object
        Parameters:
        object - the reference object with which to compare.
        Returns:
        true if this object is the same as the obj argument; false otherwise.
        See Also:
        Object.hashCode(), HashMap
      • toString

        public String toString()
        Returns a string representation of this range, such as "[3..5)" (other examples are listed in the class documentation).
        Overrides:
        toString in class Object
        Returns:
        a string representation of the object.