forked from plusone/plusone-commons
删除代表区间的 Interval,使用 guava 的 Range 即可。
This commit is contained in:
parent
7951172d68
commit
3f0c14f2d9
@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2024 the original author or authors.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* https://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 xyz.zhouxy.plusone.commons.math;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
|
||||||
import com.google.errorprone.annotations.Immutable;
|
|
||||||
|
|
||||||
import xyz.zhouxy.plusone.commons.util.Numbers;
|
|
||||||
|
|
||||||
@Immutable
|
|
||||||
public class Interval<T extends Comparable<T>> {
|
|
||||||
@Nonnull
|
|
||||||
private final IntervalType intervalType;
|
|
||||||
private final T lowerBound;
|
|
||||||
private final T upperBound;
|
|
||||||
|
|
||||||
public Interval(@Nonnull IntervalType intervalType, T lowerBound, T upperBound) {
|
|
||||||
Preconditions.checkNotNull(intervalType);
|
|
||||||
if (intervalType.isLeftClosed()) {
|
|
||||||
Preconditions.checkArgument(lowerBound != null,
|
|
||||||
"The lower bound cannot be null, when the interval is left-closed.");
|
|
||||||
}
|
|
||||||
if (intervalType.isRightClosed()) {
|
|
||||||
Preconditions.checkArgument(upperBound != null,
|
|
||||||
"The upper bound cannot be null, when the interval is right-closed.");
|
|
||||||
}
|
|
||||||
if (lowerBound != null && upperBound != null) {
|
|
||||||
Preconditions.checkArgument(lowerBound.compareTo(upperBound) <= 0,
|
|
||||||
"The lower bound must less than the upper bound.");
|
|
||||||
}
|
|
||||||
this.intervalType = intervalType;
|
|
||||||
this.lowerBound = lowerBound;
|
|
||||||
this.upperBound = upperBound;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
public final IntervalType getIntervalType() {
|
|
||||||
return intervalType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
public final Optional<T> getLowerBound() {
|
|
||||||
return Optional.ofNullable(lowerBound);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
public final Optional<T> getUpperBound() {
|
|
||||||
return Optional.ofNullable(upperBound);
|
|
||||||
}
|
|
||||||
|
|
||||||
public final boolean isLeftClosed() {
|
|
||||||
return this.intervalType.isLeftClosed();
|
|
||||||
}
|
|
||||||
|
|
||||||
public final boolean isRightClosed() {
|
|
||||||
return this.intervalType.isRightClosed();
|
|
||||||
}
|
|
||||||
|
|
||||||
public final boolean validValue(@Nonnull T value) {
|
|
||||||
return Numbers.between(value, this.lowerBound, this.upperBound, this.intervalType);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2024 the original author or authors.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* https://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 xyz.zhouxy.plusone.commons.math;
|
|
||||||
|
|
||||||
public enum IntervalType {
|
|
||||||
/** 开区间。(a,b)={x|a < x < b} */
|
|
||||||
OPEN(false, false),
|
|
||||||
/** 闭区间。[a,b]={x|a ≤ x ≤ b} */
|
|
||||||
CLOSED(true, true),
|
|
||||||
/** 左闭右开区间。[a,b)={x|a ≤ x < b} */
|
|
||||||
CLOSED_OPEN(true, false),
|
|
||||||
/** 左开右闭区间。(a,b]={x|a < x ≤ b} */
|
|
||||||
OPEN_CLOSED(false, true);
|
|
||||||
|
|
||||||
private final boolean leftClosed;
|
|
||||||
private final boolean rightClosed;
|
|
||||||
|
|
||||||
IntervalType(boolean leftClosed, boolean rightClosed) {
|
|
||||||
this.leftClosed = leftClosed;
|
|
||||||
this.rightClosed = rightClosed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final boolean isLeftClosed() {
|
|
||||||
return leftClosed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final boolean isRightClosed() {
|
|
||||||
return rightClosed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final <T extends Comparable<T>> Interval<T> buildInterval(T left, T right) {
|
|
||||||
return new Interval<>(this, left, right);
|
|
||||||
}
|
|
||||||
}
|
|
@ -18,11 +18,11 @@ package xyz.zhouxy.plusone.commons.time;
|
|||||||
|
|
||||||
import java.time.Month;
|
import java.time.Month;
|
||||||
import java.time.MonthDay;
|
import java.time.MonthDay;
|
||||||
|
import java.time.temporal.ChronoField;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.collect.Range;
|
||||||
|
|
||||||
import xyz.zhouxy.plusone.commons.annotation.StaticFactoryMethod;
|
import xyz.zhouxy.plusone.commons.annotation.StaticFactoryMethod;
|
||||||
import xyz.zhouxy.plusone.commons.util.Numbers;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 季度
|
* 季度
|
||||||
@ -43,11 +43,7 @@ public enum Quarter {
|
|||||||
/** 季度值 (1/2/3/4) */
|
/** 季度值 (1/2/3/4) */
|
||||||
private final int value;
|
private final int value;
|
||||||
|
|
||||||
/** 季度开始月份 */
|
private final Range<Integer> monthRange;
|
||||||
private final int firstMonth;
|
|
||||||
|
|
||||||
/** 季度结束月份 */
|
|
||||||
private final int lastMonth;
|
|
||||||
|
|
||||||
/** 常量值 */
|
/** 常量值 */
|
||||||
private static final Quarter[] ENUMS = Quarter.values();
|
private static final Quarter[] ENUMS = Quarter.values();
|
||||||
@ -58,8 +54,10 @@ public enum Quarter {
|
|||||||
Quarter(int value) {
|
Quarter(int value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
|
||||||
this.lastMonth = value * 3;
|
final int lastMonth = value * 3;
|
||||||
this.firstMonth = this.lastMonth - 2;
|
final int firstMonth = lastMonth - 2;
|
||||||
|
|
||||||
|
this.monthRange = Range.closed(firstMonth, lastMonth);
|
||||||
}
|
}
|
||||||
|
|
||||||
// StaticFactoryMethods
|
// StaticFactoryMethods
|
||||||
@ -73,7 +71,7 @@ public enum Quarter {
|
|||||||
*/
|
*/
|
||||||
@StaticFactoryMethod(Quarter.class)
|
@StaticFactoryMethod(Quarter.class)
|
||||||
public static Quarter fromMonth(int monthValue) {
|
public static Quarter fromMonth(int monthValue) {
|
||||||
Preconditions.checkArgument(Numbers.between(monthValue, 1, 13), "Invalid value for MonthOfYear: " + monthValue);
|
ChronoField.MONTH_OF_YEAR.checkValidValue(monthValue);
|
||||||
return of(computeQuarterValueInternal(monthValue));
|
return of(computeQuarterValueInternal(monthValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,23 +135,23 @@ public enum Quarter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Month firstMonth() {
|
public Month firstMonth() {
|
||||||
return Month.of(firstMonth);
|
return Month.of(firstMonthValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int firstMonthValue() {
|
public int firstMonthValue() {
|
||||||
return firstMonth;
|
return this.monthRange.lowerEndpoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Month lastMonth() {
|
public Month lastMonth() {
|
||||||
return Month.of(lastMonth);
|
return Month.of(lastMonthValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int lastMonthValue() {
|
public int lastMonthValue() {
|
||||||
return lastMonth;
|
return this.monthRange.upperEndpoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MonthDay firstMonthDay() {
|
public MonthDay firstMonthDay() {
|
||||||
return MonthDay.of(this.firstMonth, 1);
|
return MonthDay.of(firstMonth(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MonthDay lastMonthDay() {
|
public MonthDay lastMonthDay() {
|
||||||
@ -163,7 +161,7 @@ public enum Quarter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int firstDayOfYear(boolean leapYear) {
|
public int firstDayOfYear(boolean leapYear) {
|
||||||
return Month.of(this.firstMonth).firstDayOfYear(leapYear);
|
return firstMonth().firstDayOfYear(leapYear);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getters end
|
// Getters end
|
||||||
|
@ -18,12 +18,6 @@ package xyz.zhouxy.plusone.commons.util;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
|
||||||
|
|
||||||
import xyz.zhouxy.plusone.commons.math.IntervalType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Numbers
|
* Numbers
|
||||||
*
|
*
|
||||||
@ -81,97 +75,6 @@ public class Numbers {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// between
|
|
||||||
|
|
||||||
public static boolean between(int value, int min, int max) {
|
|
||||||
return between(value, min, max, IntervalType.CLOSED_OPEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean between(int value, int min, int max, IntervalType intervalType) {
|
|
||||||
final IntervalType intervalTypeToUse = intervalType != null
|
|
||||||
? intervalType
|
|
||||||
: IntervalType.CLOSED_OPEN;
|
|
||||||
switch (intervalTypeToUse) {
|
|
||||||
case OPEN:
|
|
||||||
return min < value && value < max;
|
|
||||||
case CLOSED:
|
|
||||||
return min <= value && value <= max;
|
|
||||||
case OPEN_CLOSED:
|
|
||||||
return min < value && value <= max;
|
|
||||||
case CLOSED_OPEN:
|
|
||||||
default:
|
|
||||||
return min <= value && value < max;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean between(long value, long min, long max) {
|
|
||||||
return between(value, min, max, IntervalType.CLOSED_OPEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean between(long value, long min, long max, IntervalType intervalType) {
|
|
||||||
final IntervalType intervalTypeToUse = intervalType != null
|
|
||||||
? intervalType
|
|
||||||
: IntervalType.CLOSED_OPEN;
|
|
||||||
switch (intervalTypeToUse) {
|
|
||||||
case OPEN:
|
|
||||||
return min < value && value < max;
|
|
||||||
case CLOSED:
|
|
||||||
return min <= value && value <= max;
|
|
||||||
case OPEN_CLOSED:
|
|
||||||
return min < value && value <= max;
|
|
||||||
case CLOSED_OPEN:
|
|
||||||
default:
|
|
||||||
return min <= value && value < max;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean between(double value, double min, double max) {
|
|
||||||
return between(value, min, max, IntervalType.CLOSED_OPEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean between(double value, double min, double max, IntervalType intervalType) {
|
|
||||||
final IntervalType intervalTypeToUse = intervalType != null
|
|
||||||
? intervalType
|
|
||||||
: IntervalType.CLOSED_OPEN;
|
|
||||||
switch (intervalTypeToUse) {
|
|
||||||
case OPEN:
|
|
||||||
return min < value && value < max;
|
|
||||||
case CLOSED:
|
|
||||||
return min <= value && value <= max;
|
|
||||||
case OPEN_CLOSED:
|
|
||||||
return min < value && value <= max;
|
|
||||||
case CLOSED_OPEN:
|
|
||||||
default:
|
|
||||||
return min <= value && value < max;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T extends Comparable<T>> boolean between(@Nonnull T value, T min, T max) {
|
|
||||||
return between(value, min, max, IntervalType.CLOSED_OPEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T extends Comparable<T>> boolean between(@Nonnull T value, T min, T max, IntervalType intervalType) {
|
|
||||||
Preconditions.checkArgument(value != null, "The value to valid connot be null.");
|
|
||||||
IntervalType intervalTypeToUse = intervalType != null
|
|
||||||
? intervalType
|
|
||||||
: IntervalType.CLOSED_OPEN;
|
|
||||||
switch (intervalTypeToUse) {
|
|
||||||
case OPEN:
|
|
||||||
return (min == null || min.compareTo(value) < 0)
|
|
||||||
&& (max == null || value.compareTo(max) < 0);
|
|
||||||
case CLOSED:
|
|
||||||
return (min == null || min.compareTo(value) <= 0)
|
|
||||||
&& (max == null || value.compareTo(max) <= 0);
|
|
||||||
case OPEN_CLOSED:
|
|
||||||
return (min == null || min.compareTo(value) < 0)
|
|
||||||
&& (max == null || value.compareTo(max) <= 0);
|
|
||||||
case CLOSED_OPEN:
|
|
||||||
default:
|
|
||||||
return (min == null || min.compareTo(value) <= 0)
|
|
||||||
&& (max == null || value.compareTo(max) < 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Numbers() {
|
private Numbers() {
|
||||||
throw new IllegalStateException("Utility class");
|
throw new IllegalStateException("Utility class");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user