All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.iofairy.range.Range Maven / Gradle / Ivy

/*
 * Copyright (C) 2021 iofairy, 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.iofairy.range;

import com.iofairy.annos.Beta;
import com.iofairy.top.G;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * Range
* See: Interval_(mathematics) *
* *
* * * *
Range Types
Notation Definition *
{@code (a, b)} {@code {x | a < x < b}} *
{@code [a, b]} {@code {x | a ≤ x ≤ b}} *
{@code (a, b]} {@code {x | a < x ≤ b}} *
{@code [a, b)} {@code {x | a ≤ x < b}} *
{@code (a, +∞)} {@code {x | x > a}} *
{@code [a, +∞)} {@code {x | x ≥ a}} *
{@code (-∞, b)} {@code {x | x < b}} *
{@code (-∞, b]} {@code {x | x ≤ b}} *
{@code (-∞, +∞)}R *
{@code [a, a]} {@code {a}} *
{@code [a, a)} {@code ∅} *
{@code (a, a]} {@code ∅} *
{@code (a, a)} {@code ∅} *
* *
* * @param Range type * @since 0.5.0 */ @Beta @SuppressWarnings("rawtypes") public class Range implements Serializable { private static final long serialVersionUID = 9999875683659872L; public static final String EMPTY_SET = "∅"; public static final String INFINITY = "∞"; public static final String SET_OF_REAL_NUMBERS = "R"; /* * lowerBound and upperBound */ /** * Lower Bound. It represents -∞ if {@code lowerBound} is null */ public final T lowerBound; /** * Upper Bound. It represents +∞ if {@code upperBound} is null */ public final T upperBound; /* * start and end */ public final T start; public final T end; /* * infimum and supremum */ public final T infimum; public final T supremum; /* * min and max */ public final T min; public final T max; /* * left and right */ public final T left; public final T right; /** * IntervalType */ public final IntervalType intervalType; public final boolean isEmpty; /** * Constructs a {@code Range}
* * NOTE:
* {@code [a,a] = {a} (a≤x≤a)}
* {@code [a,a) = ϕ (a≤x * {@code (a,a] = ϕ (a * {@code (a,a) = ϕ (a 0) { T tmpLowerBound = lowerBound; lowerBound = upperBound; upperBound = tmpLowerBound; } } this.lowerBound = lowerBound; this.upperBound = upperBound; this.start = lowerBound; this.end = upperBound; this.infimum = lowerBound; this.supremum = upperBound; this.min = lowerBound; this.max = upperBound; this.left = lowerBound; this.right = upperBound; this.isEmpty = isEmpty; } public static > Range of(T lowerBound, T upperBound, IntervalType intervalType) { return new Range<>(lowerBound, upperBound, intervalType); } public static > Range of(Range range, IntervalType intervalType) { return new Range<>(range.lowerBound, range.upperBound, intervalType); } public static > Range open(T lowerBound, T upperBound) { return of(lowerBound, upperBound, IntervalType.OPEN); } public static > Range closed(T lowerBound, T upperBound) { return of(lowerBound, upperBound, IntervalType.CLOSED); } public static > Range openClosed(T lowerBound, T upperBound) { return of(lowerBound, upperBound, IntervalType.OPEN_CLOSED); } public static > Range closedOpen(T lowerBound, T upperBound) { return of(lowerBound, upperBound, IntervalType.CLOSED_OPEN); } @SuppressWarnings("unchecked") public boolean contains(T value) { if (value == null) return false; return (lowerBound == null || (intervalType.isLeftClose() ? lowerBound.compareTo(value) <= 0 : lowerBound.compareTo(value) < 0)) && (upperBound == null || (intervalType.isRightClose() ? upperBound.compareTo(value) >= 0 : upperBound.compareTo(value) > 0)); } public boolean isEmpty() { return isEmpty; } /** * Convert list to Range list * * @param ts a list will be converted to Range list * @param sortOrNot Whether to sort. The sorting is in ascending order * @param intervalType interval Type * @param Range type * @return a list of Ranges */ public static > List> toRanges(List ts, boolean sortOrNot, IntervalType intervalType) { if (G.isEmpty(ts)) return new ArrayList<>(); if (intervalType == null) intervalType = IntervalType.CLOSED_OPEN; if (sortOrNot) { ts = new ArrayList<>(ts); Collections.sort(ts); } List> ranges = new ArrayList<>(); for (int i = 0; i < ts.size() - 1; i++) { ranges.add(new Range<>(ts.get(i), ts.get(i + 1), intervalType)); } return ranges; } public static > List> toRanges(List ts, boolean sortOrNot) { return toRanges(ts, sortOrNot, IntervalType.CLOSED_OPEN); } public static > List> toRanges(List ts) { return toRanges(ts, true, IntervalType.CLOSED_OPEN); } private static > IntervalType getIntervalType(T lowerBound, T upperBound, IntervalType intervalType) { if (lowerBound == null && upperBound == null) intervalType = IntervalType.OPEN; else if (lowerBound == null) intervalType = intervalType.isRightClose() ? IntervalType.OPEN_CLOSED : IntervalType.OPEN; else if (upperBound == null) intervalType = intervalType.isLeftClose() ? IntervalType.CLOSED_OPEN : IntervalType.OPEN; return intervalType; } @Override public String toString() { StringBuilder sb = new StringBuilder(); String lower = lowerBound == null ? "-" + INFINITY : G.toString(lowerBound); String upper = upperBound == null ? "+" + INFINITY : G.toString(upperBound); sb.append(intervalType.leftSign).append(lower).append(", ").append(upper).append(intervalType.rightSign); return sb.toString(); } public String toSimpleString() { return isEmpty ? EMPTY_SET : ((lowerBound == null && upperBound == null) ? SET_OF_REAL_NUMBERS : toString()); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy