intersection method
Returns the maximal range {@linkplain #encloses enclosed} by both this range and {@code connectedRange}, if such a range exists.
For example, the intersection of {@code [1..5]} and {@code (3..7)} is {@code (3..5]}. The resulting range may be empty; for example, {@code [1..5)} intersected with {@code [5..7)} yields the empty range {@code [5..5)}.
The intersection exists if and only if the two ranges are {@linkplain #isConnected connected}.
The intersection operation is commutative, associative and idempotent, and its identity element is {@link Range#all}).
@throws IllegalArgumentException if {@code isConnected(connectedRange)} is {@code false}
Implementation
Range<C> intersection(Range<C> connectedRange) {
int lowerCmp = lowerBound.compareTo(connectedRange.lowerBound);
int upperCmp = upperBound.compareTo(connectedRange.upperBound);
if (lowerCmp >= 0 && upperCmp <= 0) {
return this;
} else if (lowerCmp <= 0 && upperCmp >= 0) {
return connectedRange;
} else {
Cut<C> newLower =
(lowerCmp >= 0) ? lowerBound : connectedRange.lowerBound;
Cut<C> newUpper =
(upperCmp <= 0) ? upperBound : connectedRange.upperBound;
// create() would catch this, but give a confusing error message
checkArgument(
newLower.compareTo(newUpper) <= 0,
message:
"intersection is undefined for disconnected ranges $this and $connectedRange",
);
// TODO(kevinb): all the precondition checks in the constructor are redundant...
return create(newLower, newUpper);
}
}