diff --git a/hutool-core/src/main/java/cn/hutool/core/comparator/CompareUtil.java b/hutool-core/src/main/java/cn/hutool/core/comparator/CompareUtil.java index ce85293c4..afbeac703 100644 --- a/hutool-core/src/main/java/cn/hutool/core/comparator/CompareUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/comparator/CompareUtil.java @@ -352,4 +352,98 @@ public class CompareUtil { public static > T max(final T t1, final T t2) { return compare(t1, t2) >= 0 ? t1 : t2; } + + /** + * {@code null}安全的检查两个对象是否相同,通过调用{@code compare(c1, c2) == 0}完成 + * + * @param 被比较对象类型 + * @param c1 对象1,可以为{@code null} + * @param c2 对象2,可以为{@code null} + * @return 是否相等 + * @see java.util.Comparator#compare(Object, Object) + */ + public static > boolean equals(final T c1, final T c2) { + return compare(c1, c2) == 0; + } + + /** + * c1是否大于c2,通过调用{@code compare(c1, c2) > 0}完成 + * + * @param 被比较对象类型 + * @param c1 对象1,可以为{@code null} + * @param c2 对象2,可以为{@code null} + * @return c1是否大于c2 + * @see java.util.Comparator#compare(Object, Object) + */ + public static > boolean gt(final T c1, final T c2) { + return compare(c1, c2) > 0; + } + + /** + * c1是否大于或等于c2,通过调用{@code compare(c1, c2) >= 0}完成 + * + * @param 被比较对象类型 + * @param c1 对象1,可以为{@code null} + * @param c2 对象2,可以为{@code null} + * @return c1是否大于或等于c2 + * @see java.util.Comparator#compare(Object, Object) + */ + public static > boolean ge(final T c1, final T c2) { + return compare(c1, c2) >= 0; + } + + /** + * c1是否大小于c2,通过调用{@code compare(c1, c2) < 0}完成 + * + * @param 被比较对象类型 + * @param c1 对象1,可以为{@code null} + * @param c2 对象2,可以为{@code null} + * @return c1是否小于c2 + * @see java.util.Comparator#compare(Object, Object) + */ + public static > boolean lt(final T c1, final T c2) { + return compare(c1, c2) < 0; + } + + /** + * c1是否小于或等于c2,通过调用{@code compare(c1, c2) <= 0}完成 + * + * @param 被比较对象类型 + * @param c1 对象1,可以为{@code null} + * @param c2 对象2,可以为{@code null} + * @return c1是否小于或等于c2 + * @see java.util.Comparator#compare(Object, Object) + */ + public static > boolean le(final T c1, final T c2) { + return compare(c1, c2) <= 0; + } + + /** + * 给定的{@code value}是否在{@code c1}和{@code c2}的范围内
+ * 即 {@code min(c1,c2) <= value <= max(c1,c2)} + * + * @param 被比较对象类型 + * @param value 检查的对象,可以为{@code null} + * @param c1 对象1,可以为{@code null} + * @param c2 对象2,可以为{@code null} + * @return 给定的{@code value}是否在{@code c1}和{@code c2}的范围内 + */ + public static > boolean isIn(final T value, final T c1, final T c2) { + return ge(value, min(c1, c2)) && le(value, max(c1, c2)); + } + + /** + * 给定的{@code value}是否在{@code c1}和{@code c2}的范围内,但是不包括边界
+ * 即 {@code min(c1,c2) < value < max(c1,c2)} + * + * @param 被比较对象类型 + * @param value 检查的对象,可以为{@code null} + * @param c1 对象1,可以为{@code null} + * @param c2 对象2,可以为{@code null} + * @return c1是否小于或等于c2 + * @see java.util.Comparator#compare(Object, Object) + */ + public static > boolean isInExclusive(final T value, final T c1, final T c2) { + return gt(value, min(c1, c2)) && lt(value, max(c1, c2)); + } } diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/range/BoundedRange.java b/hutool-core/src/main/java/cn/hutool/core/lang/range/BoundedRange.java index 5660f7800..36776bfb4 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/range/BoundedRange.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/range/BoundedRange.java @@ -299,7 +299,7 @@ public class BoundedRange> implements Predicate< // 上界小于下界时为空 return compareValue > 0 // 上下界的边界值相等,且不为退化区间是为空 - || !(low.getType().isClose() && up.getType().isClose()); + || false == (low.getType().isClose() && up.getType().isClose()); } /** @@ -347,7 +347,7 @@ public class BoundedRange> implements Predicate< /** * {@code other}是否是当前区间的子集 * - * @param other 另一区间 + * @param other 另一个区间 * @return 是否 */ public boolean isSuperset(final BoundedRange other) { @@ -358,7 +358,7 @@ public class BoundedRange> implements Predicate< /** * {@code other}是否是当前区间的子集 * - * @param other 另一区间 + * @param other 另一个区间 * @return 是否 */ public boolean isProperSuperset(final BoundedRange other) { @@ -369,7 +369,7 @@ public class BoundedRange> implements Predicate< /** * 当前区间是否是{@code other}的子集 * - * @param other 另一区间 + * @param other 另一个区间 * @return 是否 */ public boolean isSubset(final BoundedRange other) { @@ -380,7 +380,7 @@ public class BoundedRange> implements Predicate< /** * 当前区间是否是{@code other}的真子集 * - * @param other 另一区间 + * @param other 另一个区间 * @return 是否 */ public boolean isProperSubset(final BoundedRange other) { @@ -391,34 +391,21 @@ public class BoundedRange> implements Predicate< /** * {@code other}是否与当前区间不相交 * - * @param other 另一区间 + * @param other 另一个区间 * @return 是否 */ public boolean isDisjoint(final BoundedRange other) { - return getLowerBound().compareTo(other.getUpperBound()) > 0 - || getUpperBound().compareTo(other.getLowerBound()) < 0; + return BoundedRangeOperation.isDisjoint(this, other); } /** * {@code other}是否与当前区间相交: * - * @param other 另一区间 + * @param other 另一个区间 * @return 是否 */ public boolean isIntersected(final BoundedRange other) { - return !isDisjoint(other); - } - - /** - * {@code other}与当前区间是否相等 - * - * @param other 另一区间 - * @return 是否 - */ - public boolean isEquals(final BoundedRange other) { - Objects.requireNonNull(other); - return other.getLowerBound().compareTo(getLowerBound()) == 0 - && other.getUpperBound().compareTo(getUpperBound()) == 0; + return BoundedRangeOperation.isIntersected(this, other); } /** @@ -441,7 +428,7 @@ public class BoundedRange> implements Predicate< /** * 若{@code other}与当前区间相交,则将其与当前区间合并。 * - * @param other 另一区间 + * @param other 另一个区间 * @return 合并后的新区间,若两区间不相交则返回当前集合 */ public BoundedRange unionIfIntersected(final BoundedRange other) { diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/range/BoundedRangeOperation.java b/hutool-core/src/main/java/cn/hutool/core/lang/range/BoundedRangeOperation.java index c7862b636..2b7619e88 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/range/BoundedRangeOperation.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/range/BoundedRangeOperation.java @@ -150,8 +150,9 @@ public class BoundedRangeOperation { .orElse(boundedRange); } + // region ========== 判断交并集 ========== /** - * {@code other}是否与当前区间相交 + * {@code boundedRange}是否与{@code other}相交 * * @param 可比较对象类型 * @param boundedRange 区间 @@ -163,7 +164,7 @@ public class BoundedRangeOperation { } /** - * {@code other}是否与当前区间不相交 + * {@code boundedRange}是否与{@code other}前区间不相交 * * @param 可比较对象类型 * @param boundedRange 区间 @@ -176,4 +177,5 @@ public class BoundedRangeOperation { return boundedRange.getLowerBound().compareTo(other.getUpperBound()) > 0 || boundedRange.getUpperBound().compareTo(other.getLowerBound()) < 0; } + // endregion } diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/range/FiniteBound.java b/hutool-core/src/main/java/cn/hutool/core/lang/range/FiniteBound.java index 8ebd1d37e..be63f5788 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/range/FiniteBound.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/range/FiniteBound.java @@ -1,6 +1,7 @@ package cn.hutool.core.lang.range; import cn.hutool.core.text.CharSequenceUtil; +import cn.hutool.core.util.ObjUtil; import java.util.Objects; @@ -93,31 +94,13 @@ class FiniteBound> implements Bound { return -1; } // 两值不相等,直接比较边界值 - if (!Objects.equals(getValue(), bound.getValue())) { + if (ObjUtil.notEquals(getValue(), bound.getValue())) { return getValue().compareTo(bound.getValue()); } // 两边界值相等 return compareIfSameBoundValue(bound); } - /** - * 当两个边界的值不相等时,判断它们在坐标轴上位置的先后顺序 - */ - private int compareIfSameBoundValue(final Bound bound) { - final BoundType bt1 = this.getType(); - final BoundType bt2 = bound.getType(); - // 两边界类型相同,说明连边界重合 - if (bt1 == bt2) { - return 0; - } - // 一为左边界,一为右边界,则左边界恒在右边界后 - if (bt1.isDislocated(bt2)) { - return bt1.isLowerBound() ? 1 : -1; - } - // 都为左边界,则封闭边界在前,若都为右边界,则封闭边界在后 - return Integer.compare(bt1.getCode(), bt2.getCode()); - } - /** * 获取{@code "[value"}或{@code "(value"}格式的字符串 * @@ -189,4 +172,22 @@ class FiniteBound> implements Bound { "{x | x {} {}}", type.getOperator(), value ); } + + /** + * 当两个边界的值不相等时,判断它们在坐标轴上位置的先后顺序 + */ + private int compareIfSameBoundValue(final Bound bound) { + final BoundType bt1 = this.getType(); + final BoundType bt2 = bound.getType(); + // 两边界类型相同,说明连边界重合 + if (bt1 == bt2) { + return 0; + } + // 一为左边界,一为右边界,则左边界恒在右边界后 + if (bt1.isDislocated(bt2)) { + return bt1.isLowerBound() ? 1 : -1; + } + // 都为左边界,则封闭边界在前,若都为右边界,则封闭边界在后 + return Integer.compare(bt1.getCode(), bt2.getCode()); + } } diff --git a/hutool-core/src/main/java/cn/hutool/core/math/NumberUtil.java b/hutool-core/src/main/java/cn/hutool/core/math/NumberUtil.java index 64a3d6c4b..9d5152290 100644 --- a/hutool-core/src/main/java/cn/hutool/core/math/NumberUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/math/NumberUtil.java @@ -1,5 +1,6 @@ package cn.hutool.core.math; +import cn.hutool.core.comparator.CompareUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.text.StrUtil; import cn.hutool.core.util.ArrayUtil; @@ -946,78 +947,6 @@ public class NumberUtil { return Long.parseLong(binaryStr, 2); } - /** - * 检查值是否在指定范围内 - * - * @param value 值 - * @param minInclude 最小值(包含) - * @param maxInclude 最大值(包含) - * @return 经过检查后的值 - * @since 5.8.5 - */ - public static boolean isIn(final BigDecimal value, final BigDecimal minInclude, final BigDecimal maxInclude) { - Assert.notNull(value); - Assert.notNull(minInclude); - Assert.notNull(maxInclude); - return isGreaterOrEqual(value, minInclude) && isLessOrEqual(value, maxInclude); - } - - /** - * 比较大小,参数1 > 参数2 返回true - * - * @param bigNum1 数字1 - * @param bigNum2 数字2 - * @return 是否大于 - * @since 3.0.9 - */ - public static boolean isGreater(final BigDecimal bigNum1, final BigDecimal bigNum2) { - Assert.notNull(bigNum1); - Assert.notNull(bigNum2); - return bigNum1.compareTo(bigNum2) > 0; - } - - /** - * 比较大小,参数1 >= 参数2 返回true - * - * @param bigNum1 数字1 - * @param bigNum2 数字2 - * @return 是否大于等于 - * @since 3, 0.9 - */ - public static boolean isGreaterOrEqual(final BigDecimal bigNum1, final BigDecimal bigNum2) { - Assert.notNull(bigNum1); - Assert.notNull(bigNum2); - return bigNum1.compareTo(bigNum2) >= 0; - } - - /** - * 比较大小,参数1 < 参数2 返回true - * - * @param bigNum1 数字1 - * @param bigNum2 数字2 - * @return 是否小于 - * @since 3, 0.9 - */ - public static boolean isLess(final BigDecimal bigNum1, final BigDecimal bigNum2) { - Assert.notNull(bigNum1); - Assert.notNull(bigNum2); - return bigNum1.compareTo(bigNum2) < 0; - } - - /** - * 比较大小,参数1<=参数2 返回true - * - * @param bigNum1 数字1 - * @param bigNum2 数字2 - * @return 是否小于等于 - * @since 3, 0.9 - */ - public static boolean isLessOrEqual(final BigDecimal bigNum1, final BigDecimal bigNum2) { - Assert.notNull(bigNum1); - Assert.notNull(bigNum2); - return bigNum1.compareTo(bigNum2) <= 0; - } - /** * 比较大小,值相等 返回true
* 此方法通过调用{@link Double#doubleToLongBits(double)}方法来判断是否相等
@@ -1067,17 +996,10 @@ public class NumberUtil { * @param bigNum1 数字1 * @param bigNum2 数字2 * @return 是否相等 + * @see CompareUtil#equals(Comparable, Comparable) */ public static boolean equals(final BigDecimal bigNum1, final BigDecimal bigNum2) { - //noinspection NumberEquality - if (bigNum1 == bigNum2) { - // 如果用户传入同一对象,省略compareTo以提高性能。 - return true; - } - if (bigNum1 == null || bigNum2 == null) { - return false; - } - return 0 == bigNum1.compareTo(bigNum2); + return CompareUtil.equals(bigNum1, bigNum2); } /** diff --git a/hutool-core/src/test/java/cn/hutool/core/lang/range/BoundedRangeTest.java b/hutool-core/src/test/java/cn/hutool/core/lang/range/BoundedRangeTest.java index fd1a67bba..7d36e19d1 100644 --- a/hutool-core/src/test/java/cn/hutool/core/lang/range/BoundedRangeTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/lang/range/BoundedRangeTest.java @@ -54,8 +54,8 @@ public class BoundedRangeTest { // isXXX Assert.assertFalse(range.isDisjoint(BoundedRange.open(0, 5))); - Assert.assertTrue(range.isEquals(range)); - Assert.assertFalse(range.isEquals(BoundedRange.open(0, 5))); + Assert.assertEquals(range, range); + Assert.assertNotEquals(range, BoundedRange.open(0, 5)); Assert.assertTrue(range.isIntersected(BoundedRange.open(0, 5))); Assert.assertTrue(range.isIntersected(range)); Assert.assertFalse(range.isSubset(BoundedRange.open(0, 5))); @@ -101,7 +101,7 @@ public class BoundedRangeTest { Assert.assertFalse(range.test(-1)); // isXXX - Assert.assertTrue(range.isEquals(range)); + Assert.assertEquals(range, range); Assert.assertTrue(range.isDisjoint(BoundedRange.open(-5, 0))); // (-5, 0) Assert.assertTrue(range.isDisjoint(BoundedRange.close(-5, 0))); // [-5, 0] Assert.assertTrue(range.isIntersected(BoundedRange.close(-5, 1))); // [-5, 1] @@ -142,7 +142,7 @@ public class BoundedRangeTest { Assert.assertFalse(range.test(-1)); // isXXX - Assert.assertTrue(range.isEquals(range)); + Assert.assertEquals(range, range); Assert.assertTrue(range.isDisjoint(BoundedRange.open(-5, 0))); // (-5, 0) Assert.assertTrue(range.isDisjoint(BoundedRange.close(-5, 0))); // [-5, 0] Assert.assertTrue(range.isIntersected(BoundedRange.open(-5, 1))); // [-5, 1]