RangeMapEntry(Cut<K> lowerBound, Cut<K> upperBound, V value) { this(Range.create(lowerBound, upperBound), value); }
@Override public Range<C> span() { if (ranges.isEmpty()) { throw new NoSuchElementException(); } return Range.create(ranges.get(0).lowerBound, ranges.get(ranges.size() - 1).upperBound); }
@Override public Range<K> span() { if (ranges.isEmpty()) { throw new NoSuchElementException(); } Range<K> firstRange = ranges.get(0); Range<K> lastRange = ranges.get(ranges.size() - 1); return Range.create(firstRange.lowerBound, lastRange.upperBound); }
@Override public Range<C> span() { Entry<Cut<C>, Range<C>> firstEntry = rangesByLowerBound.firstEntry(); Entry<Cut<C>, Range<C>> lastEntry = rangesByLowerBound.lastEntry(); if (firstEntry == null) { throw new NoSuchElementException(); } return Range.create(firstEntry.getValue().lowerBound, lastEntry.getValue().upperBound); }
/** * Returns the maximal range lying between this range and {@code otherRange}, if such a range * exists. The resulting range may be empty if the two ranges are adjacent but non-overlapping. * * <p>For example, the gap of {@code [1..5]} and {@code (7..10)} is {@code (5..7]}. The resulting * range may be empty; for example, the gap between {@code [1..5)} {@code [5..7)} yields the empty * range {@code [5..5)}. * * <p>The gap exists if and only if the two ranges are either disconnected or immediately adjacent * (any intersection must be an empty range). * * <p>The gap operation is commutative. * * @throws IllegalArgumentException if this range and {@code otherRange} have a nonempty * intersection * @since 27.0 */ public Range<C> gap(Range<C> otherRange) { boolean isThisFirst = this.lowerBound.compareTo(otherRange.lowerBound) < 0; Range<C> firstRange = isThisFirst ? this : otherRange; Range<C> secondRange = isThisFirst ? otherRange : this; return create(firstRange.upperBound, secondRange.lowerBound); }
/** * Returns a range that contains all values greater than or equal to {@code lower} and less than * or equal to {@code upper}. * * @throws IllegalArgumentException if {@code lower} is greater than {@code upper} * @throws ClassCastException if {@code lower} and {@code upper} are not mutually comparable * @since 14.0 */ public static <C extends Comparable<?>> Range<C> closed(C lower, C upper) { return create(Cut.belowValue(lower), Cut.aboveValue(upper)); }
/** * Returns a range that contains all values greater than or equal to {@code lower} and strictly * less than {@code upper}. * * @throws IllegalArgumentException if {@code lower} is greater than {@code upper} * @throws ClassCastException if {@code lower} and {@code upper} are not mutually comparable * @since 14.0 */ public static <C extends Comparable<?>> Range<C> closedOpen(C lower, C upper) { return create(Cut.belowValue(lower), Cut.belowValue(upper)); }
/** * Returns a range that contains all values less than or equal to {@code endpoint}. * * @since 14.0 */ public static <C extends Comparable<?>> Range<C> atMost(C endpoint) { return create(Cut.<C>belowAll(), Cut.aboveValue(endpoint)); }
/** * Returns a range that contains all values strictly greater than {@code lower} and less than or * equal to {@code upper}. * * @throws IllegalArgumentException if {@code lower} is greater than {@code upper} * @throws ClassCastException if {@code lower} and {@code upper} are not mutually comparable * @since 14.0 */ public static <C extends Comparable<?>> Range<C> openClosed(C lower, C upper) { return create(Cut.aboveValue(lower), Cut.aboveValue(upper)); }
/** * Returns a range that contains all values strictly greater than {@code endpoint}. * * @since 14.0 */ public static <C extends Comparable<?>> Range<C> greaterThan(C endpoint) { return create(Cut.aboveValue(endpoint), Cut.<C>aboveAll()); }
/** * Returns a range that contains all values strictly less than {@code endpoint}. * * @since 14.0 */ public static <C extends Comparable<?>> Range<C> lessThan(C endpoint) { return create(Cut.<C>belowAll(), Cut.belowValue(endpoint)); }
@Override public Range<C> range(BoundType lowerBoundType, BoundType upperBoundType) { return Range.create( range.lowerBound.withLowerBoundType(lowerBoundType, domain), range.upperBound.withUpperBoundType(upperBoundType, domain)); }
/** * Returns a range that contains all values greater than or equal to {@code endpoint}. * * @since 14.0 */ public static <C extends Comparable<?>> Range<C> atLeast(C endpoint) { return create(Cut.belowValue(endpoint), Cut.<C>aboveAll()); }
/** * Returns a range that contains all values strictly greater than {@code lower} and strictly less * than {@code upper}. * * @throws IllegalArgumentException if {@code lower} is greater than <i>or equal to</i> {@code * upper} * @throws ClassCastException if {@code lower} and {@code upper} are not mutually comparable * @since 14.0 */ public static <C extends Comparable<?>> Range<C> open(C lower, C upper) { return create(Cut.aboveValue(lower), Cut.belowValue(upper)); }
@Override public Range<K> span() { Entry<Cut<K>, RangeMapEntry<K, V>> firstEntry = entriesByLowerBound.firstEntry(); Entry<Cut<K>, RangeMapEntry<K, V>> lastEntry = entriesByLowerBound.lastEntry(); if (firstEntry == null) { throw new NoSuchElementException(); } return Range.create( firstEntry.getValue().getKey().lowerBound, lastEntry.getValue().getKey().upperBound); }
/** * Returns the minimal range that {@linkplain #encloses encloses} both this range and {@code * other}. For example, the span of {@code [1..3]} and {@code (5..7)} is {@code [1..7)}. * * <p><i>If</i> the input ranges are {@linkplain #isConnected connected}, the returned range can * also be called their <i>union</i>. If they are not, note that the span might contain values * that are not contained in either input range. * * <p>Like {@link #intersection(Range) intersection}, this operation is commutative, associative * and idempotent. Unlike it, it is always well-defined for any two input ranges. */ public Range<C> span(Range<C> other) { int lowerCmp = lowerBound.compareTo(other.lowerBound); int upperCmp = upperBound.compareTo(other.upperBound); if (lowerCmp <= 0 && upperCmp >= 0) { return this; } else if (lowerCmp >= 0 && upperCmp <= 0) { return other; } else { Cut<C> newLower = (lowerCmp <= 0) ? lowerBound : other.lowerBound; Cut<C> newUpper = (upperCmp >= 0) ? upperBound : other.upperBound; return create(newLower, newUpper); } }
/** * Returns a range that contains any value from {@code lower} to {@code upper}, where each * endpoint may be either inclusive (closed) or exclusive (open). * * @throws IllegalArgumentException if {@code lower} is greater than {@code upper} * @throws ClassCastException if {@code lower} and {@code upper} are not mutually comparable * @since 14.0 */ public static <C extends Comparable<?>> Range<C> range( C lower, BoundType lowerType, C upper, BoundType upperType) { checkNotNull(lowerType); checkNotNull(upperType); Cut<C> lowerBound = (lowerType == BoundType.OPEN) ? Cut.aboveValue(lower) : Cut.belowValue(lower); Cut<C> upperBound = (upperType == BoundType.OPEN) ? Cut.belowValue(upper) : Cut.aboveValue(upper); return create(lowerBound, upperBound); }
@Override protected Entry<Cut<C>, Range<C>> computeNext() { if (complementLowerBoundWindow.upperBound.isLessThan(nextComplementRangeLowerBound) || nextComplementRangeLowerBound == Cut.<C>aboveAll()) { return endOfData(); } Range<C> negativeRange; if (positiveItr.hasNext()) { Range<C> positiveRange = positiveItr.next(); negativeRange = Range.create(nextComplementRangeLowerBound, positiveRange.lowerBound); nextComplementRangeLowerBound = positiveRange.upperBound; } else { negativeRange = Range.create(nextComplementRangeLowerBound, Cut.<C>aboveAll()); nextComplementRangeLowerBound = Cut.aboveAll(); } return Maps.immutableEntry(negativeRange.lowerBound, negativeRange); } };
@Override protected Entry<Cut<C>, Range<C>> computeNext() { if (nextComplementRangeUpperBound == Cut.<C>belowAll()) { return endOfData(); } else if (positiveItr.hasNext()) { Range<C> positiveRange = positiveItr.next(); Range<C> negativeRange = Range.create(positiveRange.upperBound, nextComplementRangeUpperBound); nextComplementRangeUpperBound = positiveRange.lowerBound; if (complementLowerBoundWindow.lowerBound.isLessThan(negativeRange.lowerBound)) { return Maps.immutableEntry(negativeRange.lowerBound, negativeRange); } } else if (complementLowerBoundWindow.lowerBound.isLessThan(Cut.<C>belowAll())) { Range<C> negativeRange = Range.create(Cut.<C>belowAll(), nextComplementRangeUpperBound); nextComplementRangeUpperBound = Cut.belowAll(); return Maps.immutableEntry(Cut.<C>belowAll(), negativeRange); } return endOfData(); } };
public static Range<?> instantiate(SerializationStreamReader reader) throws SerializationException { Cut lowerBound; boolean hasLowerBound = reader.readBoolean(); if (hasLowerBound) { boolean lowerIsClosed = reader.readBoolean(); Comparable lower = (Comparable) reader.readObject(); lowerBound = lowerIsClosed ? Cut.belowValue(lower) : Cut.aboveValue(lower); } else { lowerBound = Cut.belowAll(); } Cut upperBound; boolean hasUpperBound = reader.readBoolean(); if (hasUpperBound) { boolean upperIsClosed = reader.readBoolean(); Comparable upper = (Comparable) reader.readObject(); upperBound = upperIsClosed ? Cut.aboveValue(upper) : Cut.belowValue(upper); } else { upperBound = Cut.aboveAll(); } return Range.create(lowerBound, upperBound); }