/** * Clamps {@code value} to this range. * * <p>If the value is within this range, it is returned. Otherwise, if it is {@code <} than the * lower endpoint, the lower endpoint is returned, else the upper endpoint is returned. * Comparisons are performed using the {@link Comparable} interface. * * @param value a non-{@code null} {@code T} reference * @return {@code value} clamped to this range. */ public T clamp(T value) { checkNotNull(value, "value must not be null"); if (value.compareTo(mLower) < 0) { return mLower; } else if (value.compareTo(mUpper) > 0) { return mUpper; } else { return value; } }
/** * Returns the smallest range that includes this range and the inclusive range specified by {@code * [lower, upper]}. * * <p>See {@link #extend(Range)} for more details. * * @param lower a non-{@code null} {@code T} reference * @param upper a non-{@code null} {@code T} reference * @return the extension of this range and the other range. * @throws NullPointerException if {@code lower} or {@code upper} was {@code null} */ public Range<T> extend(T lower, T upper) { checkNotNull(lower, "lower must not be null"); checkNotNull(upper, "upper must not be null"); int cmpLower = lower.compareTo(mLower); int cmpUpper = upper.compareTo(mUpper); if (cmpLower >= 0 && cmpUpper <= 0) { // this inludes other return this; } else { return Range.create(cmpLower >= 0 ? mLower : lower, cmpUpper <= 0 ? mUpper : upper); } }
/** * Returns the intersection of this range and the inclusive range specified by {@code [lower, * upper]}. * * <p>See {@link #intersect(Range)} for more details. * * @param lower a non-{@code null} {@code T} reference * @param upper a non-{@code null} {@code T} reference * @return the intersection of this range and the other range * @throws NullPointerException if {@code lower} or {@code upper} was {@code null} * @throws IllegalArgumentException if the ranges are disjoint. */ public Range<T> intersect(T lower, T upper) { checkNotNull(lower, "lower must not be null"); checkNotNull(upper, "upper must not be null"); int cmpLower = lower.compareTo(mLower); int cmpUpper = upper.compareTo(mUpper); if (cmpLower <= 0 && cmpUpper >= 0) { // [lower, upper] includes this return this; } else { return Range.create(cmpLower <= 0 ? mLower : lower, cmpUpper >= 0 ? mUpper : upper); } }
/** * Checks if the {@code value} is within the bounds of this range. * * <p>A value is considered to be within this range if it's {@code >=} the lower endpoint * <i>and</i> {@code <=} the upper endpoint (using the {@link Comparable} interface.) * * @param value a non-{@code null} {@code T} reference * @return {@code true} if the value is within this inclusive range, {@code false} otherwise * @throws NullPointerException if {@code value} was {@code null} */ public boolean contains(T value) { checkNotNull(value, "value must not be null"); boolean gteLower = value.compareTo(mLower) >= 0; boolean lteUpper = value.compareTo(mUpper) <= 0; return gteLower && lteUpper; }
/** * Create a new immutable range. * * <p>The endpoints are {@code [lower, upper]}; that is the range is bounded. {@code lower} must * be {@link Comparable#compareTo lesser or equal} to {@code upper}. * * @param lower The lower endpoint (inclusive) * @param upper The upper endpoint (inclusive) * @throws NullPointerException if {@code lower} or {@code upper} is {@code null} */ public Range(final T lower, final T upper) { mLower = checkNotNull(lower, "lower must not be null"); mUpper = checkNotNull(upper, "upper must not be null"); if (lower.compareTo(upper) > 0) { throw new IllegalArgumentException("lower must be less than or equal to upper"); } }