# Class Range<E extends Comparable<? super E>>

Object
Range<E>

Type Parameters:
  `E` - the type of range elements, typically a `Number` subclass or `Date`.

All Implemented Interfaces:
  `Serializable, Formattable, CheckedContainer<E>, Emptiable`

Direct Known Subclasses:
  `NumberRange`

public class Range<E extends Comparable<? super E>> extends Object implements CheckedContainer<E>, Formattable, Emptiable, Serializable
A set of minimum and maximum values of a certain class, allowing a user to determine if a value of the same class is contained inside the range. The minimum and maximum values do not have to be included in the range, and can be null. If the minimum or maximum values are null, the range is said to be unbounded on that endpoint. If both the minimum and maximum are null, the range is completely unbounded and all values of that class are contained within the range. Null values are always considered exclusive, since iterations over the values will never reach the infinite endpoint.

The minimal and maximal values (the endpoints) may be inclusive or exclusive. Numeric ranges where both endpoints are inclusive are called closed intervals and are represented by square brackets, for example "`[0 … 255]`". Numeric ranges where both endpoints are exclusive are called open intervals and are represented by parenthesis, for example "`(0 … 256)`".

## Type and value of range elements

To be a member of a `Range`, the `<E>` type defining the range must implement the `Comparable` interface. All argument values given to the methods of this class shall be or contain instances of that `<E>` type. The type is enforced by parameterized type, but some subclasses may put additional constraints. For example, `MeasurementRange` will additionally checks the units of measurement. Consequently, every methods defined in this class may throw an `IllegalArgumentException` if a given argument does not met some constraint beyond the type.

## Relationship with ISO 19123 definition of range

The ISO 19123 standard (Coverage geometry and functions) defines the range as the set (either finite or transfinite) of feature attribute values associated by a function (the coverage) with the elements of the coverage domain. In other words, if we see a coverage as a function, then a range is the set of possible return values.

The characteristics of the spatial domain are defined by the ISO 19123 standard whereas the characteristics of the attribute range are not part of that standard. In Apache SIS, those characteristics are described by the `SampleDimension` class, which may contain one or many `Range` instances. Consequently, this `Range` class is closely related, but not identical, to the ISO 19123 definition or range.

Ranges are not necessarily numeric. Numeric and non-numeric ranges can be associated to discrete coverages, while typically only numeric ranges can be associated to continuous coverages.

## Immutability and thread safety

This class and the `NumberRange` / `MeasurementRange` subclasses are immutable, and thus inherently thread-safe. Other subclasses may or may not be immutable, at implementation choice. But implementers are encouraged to make sure that all subclasses remain immutable for more predictable behavior.

Since:
  0.3
See Also:
  - `RangeFormat`
  - `RangeSet`
  - Serialized Form

- ## Nested Class Summary

  ### Nested classes/interfaces inherited from interface CheckedContainer

  `CheckedContainer​.Mutability`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `Range(Class<E> elementType, E minValue, boolean isMinIncluded, E maxValue, boolean isMaxIncluded)`
  Creates a new range bounded by the given endpoint values.
  `Range(Range<E> range)`
  Constructs a range with the same type and the same values as the specified range.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `boolean`
  `contains(E value)`
  Returns `true` if this range contains the given value.
  `boolean`
  `contains(Range<? extends E> range)`
  Returns `true` if the supplied range is fully contained within this range.
  `boolean`
  `equals(Object object)`
  Compares this range with the given object for equality.
  `void`
  `formatTo(Formatter formatter, int flags, int width, int precision)`
  Formats this range using the provided formatter.
  `Class<E>`
  `getElementType()`
  Returns the base type of elements in this range.
  `E`
  `getMaxValue()`
  Returns the maximal value, or `null` if this range has no upper limit.
  `E`
  `getMinValue()`
  Returns the minimal value, or `null` if this range has no lower limit.
  `CheckedContainer​.Mutability`
  `getMutability()`
  Indicates that this range is immutable (at least by default).
  `int`
  `hashCode()`
  Returns a hash code value for this range.
  `Range<E>`
  `intersect(Range<E> range)`
  Returns the intersection between this range and the given range.
  `boolean`
  `intersects(Range<? extends E> range)`
  Returns `true` if this range intersects the given range.
  `boolean`
  `isBounded()`
  Returns `true` if this range is both left-bounded and right-bounded.
  `final boolean`
  `isEmpty()`
  Returns `true` if this range is empty.
  `boolean`
  `isMaxIncluded()`
  Returns `true` if the maximal value is inclusive, or `false` if exclusive.
  `boolean`
  `isMinIncluded()`
  Returns `true` if the minimal value is inclusive, or `false` if exclusive.
  `Range<E>[]`
  `subtract(Range<E> range)`
  Returns the range of values that are in this range but not in the given range.
  `String`
  `toString()`
  Returns a unlocalized string representation of this range.
  `Range<E>`
  `union(Range<E> range)`
  Returns the union of this range with the given range.

  ### Methods inherited from class Object

  `clone, finalize, getClass, notify, notifyAll, wait, wait, wait`

- ## Constructor Details

  - ### Range

    public Range(Range<E> range)
    Constructs a range with the same type and the same values as the specified range. This is a copy constructor.
    Parameters:
      `range` - the range to copy.

  - ### Range

    public Range(Class<E> elementType, E minValue, boolean isMinIncluded, E maxValue, boolean isMaxIncluded)
    Creates a new range bounded by the given endpoint values. If the given minimum value is greater than the maximum value, then the range is empty.

    #### Assertion

    This constructor verifies the `minValue` and `maxValue` arguments type if Java assertions are enabled. This verification is not performed in normal execution because theoretically unnecessary unless Java generic types have been tricked.
    Parameters:
      `elementType` - the base type of the range elements.
      `minValue` - the minimal value, or `null` if none.
      `isMinIncluded` - `true` if the minimal value is inclusive, or `false` if exclusive.
      `maxValue` - the maximal value, or `null` if none.
      `isMaxIncluded` - `true` if the maximal value is inclusive, or `false` if exclusive.
    Throws:
      `AssertionError` - if assertions are enabled and the given values are not compatible with the given type.

- ## Method Details

  - ### getMutability

    public CheckedContainer.Mutability getMutability()
    Indicates that this range is immutable (at least by default).
    Specified by:
      `getMutability` in interface `CheckedContainer<E extends Comparable<? super E>>`
    Returns:
      `CheckedContainer​.Mutability​.IMMUTABLE` by default.
    Since:
      1.6

  - ### getElementType

    public Class<E> getElementType()
    Returns the base type of elements in this range. This is the type specified at construction time.
    Specified by:
      `getElementType` in interface `CheckedContainer<E extends Comparable<? super E>>`
    Returns:
      the element type.

  - ### getMinValue

    public E getMinValue()
    Returns the minimal value, or `null` if this range has no lower limit. If non-null, the returned value is either inclusive or exclusive depending on the boolean returned by `isMinIncluded()`.
    Returns:
      the minimal value, or `null` if this range is unbounded on the lower side.

  - ### isMinIncluded

    public boolean isMinIncluded()
    Returns `true` if the minimal value is inclusive, or `false` if exclusive. Note that `null` values are always considered exclusive.
    Returns:
      `true` if the minimal value is inclusive, or `false` if exclusive.

  - ### getMaxValue

    public E getMaxValue()
    Returns the maximal value, or `null` if this range has no upper limit. If non-null, the returned value is either inclusive or exclusive depending on the boolean returned by `isMaxIncluded()`.
    Returns:
      the maximal value, or `null` if this range is unbounded on the upper side.

  - ### isMaxIncluded

    public boolean isMaxIncluded()
    Returns `true` if the maximal value is inclusive, or `false` if exclusive. Note that `null` values are always considered exclusive.
    Returns:
      `true` if the maximal value is inclusive, or `false` if exclusive.

  - ### isEmpty

    public final boolean isEmpty()
    Returns `true` if this range is empty. A range is empty if the minimum value is greater than the maximum value, or if they are equal while at least one of them is exclusive, or if both bounds are NaN.

    #### API note

    This method is final because often used by the internal implementation. Making the method final ensures that the other methods behave consistently.
    Specified by:
      `isEmpty` in interface `Emptiable`
    Returns:
      `true` if this range is empty.

  - ### isBounded

    public boolean isBounded()
    Returns `true` if this range is both left-bounded and right-bounded. A `true` return value guarantees that:
    1. both `getMinValue()` and `getMaxValue()` will return non-null values;
    2. if minimum and maximum values are numbers, then those numbers are finite.
    Returns:
      whether this range is left- and right-bounded.
    Since:
      1.0

  - ### contains

    public boolean contains(E value)
    Returns `true` if this range contains the given value. A range never contains the `null` value. This is consistent with the class javadoc stating that null minimum or maximum values are exclusive.
    Parameters:
      `value` - the value to check for inclusion in this range.
    Returns:
      `true` if the given value is included in this range.

  - ### contains

    public boolean contains(Range<? extends E> range)
    Returns `true` if the supplied range is fully contained within this range.
    Parameters:
      `range` - the range to check for inclusion in this range.
    Returns:
      `true` if the given range is included in this range.
    Throws:
      `IllegalArgumentException` - if the given range is incompatible, for example because of incommensurable units of measurement.

  - ### intersects

    public boolean intersects(Range<? extends E> range)
    Returns `true` if this range intersects the given range.
    Parameters:
      `range` - the range to check for intersection with this range.
    Returns:
      `true` if the given range intersects this range.
    Throws:
      `IllegalArgumentException` - if the given range is incompatible, for example because of incommensurable units of measurement.

  - ### intersect

    public Range<E> intersect(Range<E> range)
    Returns the intersection between this range and the given range.
    Parameters:
      `range` - the range to intersect.
    Returns:
      the intersection of this range with the given range.
    Throws:
      `IllegalArgumentException` - if the given range is incompatible, for example because of incommensurable units of measurement.

  - ### union

    public Range<E> union(Range<E> range)
    Returns the union of this range with the given range.
    Parameters:
      `range` - the range to add to this range.
    Returns:
      the union of this range with the given range.
    Throws:
      `IllegalArgumentException` - if the given range is incompatible, for example because of incommensurable units of measurement.

  - ### subtract

    public Range<E>[] subtract(Range<E> range)
    Returns the range of values that are in this range but not in the given range. This method returns an array of length 0, 1 or 2:
    - If the given range contains fully this range, returns an array of length 0.
    - If the given range is in the middle of this range, then the subtraction results in two disjoint ranges which will be returned as two elements in the array.
    - Otherwise returns an array of length 1.
    Parameters:
      `range` - the range to subtract.
    Returns:
      this range without the given range, as an array of length 0, 1 or 2.
    Throws:
      `IllegalArgumentException` - if the given range is incompatible, for example because of incommensurable units of measurement.

  - ### equals

    public boolean equals(Object object)
    Compares this range with the given object for equality. Two ranges are considered equal if they met the following conditions:
    - They are of the same class.
    - They have the same element type.
    - Both ranges are empty, or (if at least one range is non-empty):
      - They have equal minimum value in the sense of `Object​.equals(Object)`.
      - They have equal maximum value in the sense of `Object​.equals(Object)`.
      - They have equal inclusive minimum flag.
      - They have equal inclusive maximum flag.
    - Any other requirement added by subclasses. In particular `MeasurementRange` compares also the units of measurement.
    Note that this method may return `true` even if the bounds are not strictly identical. In particular this method returns `true` if the ranges are empty regardless their minimum and maximum values, and also returns `true` if the bounds are wrappers for some `Float​.NaN` or `Double​.NaN` values even if their raw bits pattern are not the same. The latter is because `Float​.equals(Object)` and `Double​.equals(Object)` consider all NaN values as equal.
    Overrides:
      `equals` in class `Object`
    Parameters:
      `object` - the object to compare with this range for equality.
    Returns:
      `true` if the given object is equal to this range.

  - ### hashCode

    public int hashCode()
    Returns a hash code value for this range.
    Overrides:
      `hashCode` in class `Object`

  - ### toString

    public String toString()
    Returns a unlocalized string representation of this range. This method complies to the format described in the ISO 31-11 standard, except that the minimal and maximal values are separated by the "`…`" character instead of coma. More specifically, the string representation is defined as below:
    - If the range is empty, then this method returns "`{}`".
    - Otherwise if the minimal value is equal to the maximal value, then the string representation of that value is returned inside braces as in "`{value}`".
    - Otherwise the string representation of the minimal and maximal values are formatted like "`[min … max]`" for inclusive endpoints or "`(min … max)`" for exclusive endpoints, or a mix of both styles. The "`∞`" symbol is used in place of `min` or `max` for unbounded ranges.
    If this range is a `MeasurementRange`, then the unit of measurement is appended to the above string representation except for empty ranges.
    Overrides:
      `toString` in class `Object`
    See Also:
      - `RangeFormat`
      - Wikipedia: ISO 31-11

  - ### formatTo

    public void formatTo(Formatter formatter, int flags, int width, int precision)
    Formats this range using the provided formatter. This method is invoked when a `Range` object is formatted using the `"%s"` conversion specifier of `Formatter`. Users don't need to invoke this method explicitly.

    If the alternate flags is present (as in `"%#s"`), then the range will be formatted using the alternate form for exclusive bounds.

    Specified by:
      `formatTo` in interface `Formattable`
    Parameters:
      `formatter` - the formatter in which to format this range.
      `flags` - `FormattableFlags​.LEFT_JUSTIFY` for left alignment, or 0 for right alignment.
      `width` - minimal number of characters to write, padding with `' '` if necessary.
      `precision` - maximal number of characters to write, or -1 if no limit.