diff --git a/CHANGELOG.md b/CHANGELOG.md
index e44903d7b..1949a5b45 100755
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,8 @@
* 【core 】 SerializeUtil.deserialize增加白名单类,避免RCE vulnerability(issue#3021@Github)
* 【poi 】 ExcelWriter在关闭后不清空currentRow,以便复用(issue#3025@Github)
* 【core 】 完善HttpStatus,参考相关规范,补全缺失的状态码(pr#968@Gitee)
+* 【core 】 NumberUtil增加(pr#968@Gitee)
+* 【core 】 Number128增加hash和equals方法(pr#968@Gitee)
### 🐞Bug修复
* 【core 】 CollUtil.split优化切割列表参数判断,避免OOM(pr#3026@Github)
diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/hash/Number128.java b/hutool-core/src/main/java/cn/hutool/core/lang/hash/Number128.java
index 12e0a8c35..dc2ff5e06 100644
--- a/hutool-core/src/main/java/cn/hutool/core/lang/hash/Number128.java
+++ b/hutool-core/src/main/java/cn/hutool/core/lang/hash/Number128.java
@@ -1,5 +1,7 @@
package cn.hutool.core.lang.hash;
+import java.util.Objects;
+
/**
* 128位数字表示,分高位和低位
*
@@ -87,4 +89,19 @@ public class Number128 extends Number {
public double doubleValue() {
return longValue();
}
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ final Number128 number128 = (Number128) o;
+ return lowValue == number128.lowValue && highValue == number128.highValue;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(lowValue, highValue);
+ }
}
diff --git a/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java
index ad8e853eb..ee24c1122 100755
--- a/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java
@@ -13,6 +13,7 @@ import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Collection;
import java.util.HashSet;
+import java.util.Objects;
import java.util.Set;
/**
@@ -113,6 +114,12 @@ public class NumberUtil {
* 提供精确的加法运算
* 如果传入多个值为null或者空,则返回0
*
+ *
+ * 需要注意的是,在不同Locale下,数字的表示形式也是不同的,例如:
+ * 德国、荷兰、比利时、丹麦、意大利、罗马尼亚和欧洲大多地区使用`,`区分小数
+ * 也就是说,在这些国家地区,1.20表示120,而非1.2。
+ *
+ *
* @param v1 被加数
* @param v2 加数
* @return 和
@@ -125,6 +132,12 @@ public class NumberUtil {
* 提供精确的加法运算
* 如果传入多个值为null或者空,则返回0
*
+ *
+ * 需要注意的是,在不同Locale下,数字的表示形式也是不同的,例如:
+ * 德国、荷兰、比利时、丹麦、意大利、罗马尼亚和欧洲大多地区使用`,`区分小数
+ * 也就是说,在这些国家地区,1.20表示120,而非1.2。
+ *
+ *
* @param values 多个被加值
* @return 和
* @since 4.0.0
@@ -1871,6 +1884,31 @@ public class NumberUtil {
return num1 == num2;
}
+ /**
+ * 比较数字值是否相等,相等返回{@code true}
+ * 需要注意的是{@link BigDecimal}需要特殊处理
+ * BigDecimal使用compareTo方式判断,因为使用equals方法也判断小数位数,如2.0和2.00就不相等,
+ * 此方法判断值相等时忽略精度的,即0.00 == 0
+ *
+ *
+ * - 如果用户提供两个Number都是{@link BigDecimal},则通过调用{@link BigDecimal#compareTo(BigDecimal)}方法来判断是否相等
+ * - 其他情况调用{@link Number#equals(Object)}比较
+ *
+ *
+ * @param number1 数字1
+ * @param number2 数字2
+ * @return 是否相等
+ * @see Objects#equals(Object, Object)
+ * @since 5.8.17
+ */
+ public static boolean equals(final Number number1, final Number number2) {
+ if (number1 instanceof BigDecimal && number2 instanceof BigDecimal) {
+ // BigDecimal使用compareTo方式判断,因为使用equals方法也判断小数位数,如2.0和2.00就不相等
+ return equals((BigDecimal) number1, (BigDecimal) number2);
+ }
+ return Objects.equals(number1, number2);
+ }
+
/**
* 比较大小,值相等 返回true
* 此方法通过调用{@link BigDecimal#compareTo(BigDecimal)}方法来判断是否相等
@@ -2548,6 +2586,12 @@ public class NumberUtil {
* 将指定字符串转换为{@link Number} 对象
* 此方法不支持科学计数法
*
+ *
+ * 需要注意的是,在不同Locale下,数字的表示形式也是不同的,例如:
+ * 德国、荷兰、比利时、丹麦、意大利、罗马尼亚和欧洲大多地区使用`,`区分小数
+ * 也就是说,在这些国家地区,1.20表示120,而非1.2。
+ *
+ *
* @param numberStr Number字符串
* @return Number对象
* @throws NumberFormatException 包装了{@link ParseException},当给定的数字字符串无法解析时抛出
diff --git a/hutool-core/src/main/java/cn/hutool/core/util/ObjectUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/ObjectUtil.java
index 62d6f005a..02f7b48ee 100644
--- a/hutool-core/src/main/java/cn/hutool/core/util/ObjectUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/util/ObjectUtil.java
@@ -7,7 +7,6 @@ import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.map.MapUtil;
import java.lang.reflect.Array;
-import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -53,8 +52,8 @@ public class ObjectUtil {
* @see Objects#equals(Object, Object)
*/
public static boolean equal(Object obj1, Object obj2) {
- if (obj1 instanceof BigDecimal && obj2 instanceof BigDecimal) {
- return NumberUtil.equals((BigDecimal) obj1, (BigDecimal) obj2);
+ if (obj1 instanceof Number && obj2 instanceof Number) {
+ return NumberUtil.equals((Number) obj1, (Number) obj2);
}
return Objects.equals(obj1, obj2);
}
diff --git a/hutool-core/src/test/java/cn/hutool/core/text/NamingCaseTest.java b/hutool-core/src/test/java/cn/hutool/core/text/NamingCaseTest.java
index 2eec1a248..c1df9f67e 100755
--- a/hutool-core/src/test/java/cn/hutool/core/text/NamingCaseTest.java
+++ b/hutool-core/src/test/java/cn/hutool/core/text/NamingCaseTest.java
@@ -1,5 +1,6 @@
package cn.hutool.core.text;
+import cn.hutool.core.lang.Console;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.CharUtil;
import org.junit.Assert;
@@ -41,4 +42,10 @@ public class NamingCaseTest {
.set("DEPT_NAME","DEPT_NAME")
.forEach((key, value) -> Assert.assertEquals(value, NamingCase.toUnderlineCase(key)));
}
+
+ @Test
+ public void issue3031Test() {
+ final String camelCase = NamingCase.toCamelCase("user_name,BIRTHDAY");
+ Assert.assertEquals("userName,birthday", camelCase);
+ }
}
diff --git a/hutool-crypto/src/test/java/cn/hutool/crypto/asymmetric/SM2Test.java b/hutool-crypto/src/test/java/cn/hutool/crypto/asymmetric/SM2Test.java
index 73a88e635..b007642c2 100644
--- a/hutool-crypto/src/test/java/cn/hutool/crypto/asymmetric/SM2Test.java
+++ b/hutool-crypto/src/test/java/cn/hutool/crypto/asymmetric/SM2Test.java
@@ -330,4 +330,10 @@ public class SM2Test {
// 04占位一个字节
Assert.assertEquals(65, sm2.getQ(false).length);
}
+
+ @Test
+ public void issueI6ROLTTest(){
+ String publicKey = "04bf347dfa32b9bc4c378232898ea43a210887a9b9ed6cc188f91b653706b44fa8434518d54412606788f34be8097cc233608f780edaf695c7e2b1d1c1b7b0d7c3";
+ new SM2(null, publicKey);
+ }
}