2 Commits

Author SHA1 Message Date
825a99dab6 test: 完善 Numbers#sum(BigInteger...) 的单元测试 2025-08-20 17:02:04 +08:00
f3218420ed feat: Numbers 类新增 parseXxx 方法
`Numbers` 类新增 `parseXxx` 方法用于将字符串转为对应类型的数字,当转换失败时返回默认值。默认值允许为 `null`。
2025-08-20 17:00:37 +08:00
2 changed files with 225 additions and 2 deletions

View File

@@ -29,7 +29,9 @@ import javax.annotation.Nullable;
*/
public class Numbers {
// ================================
// #region - sum
// ================================
/**
* 求和
@@ -131,9 +133,13 @@ public class Numbers {
return BigDecimals.sum(numbers);
}
// ================================
// #endregion
// ================================
// ================================
// #region - nullToZero
// ================================
/**
* 将 {@code null} 转换为 {@code 0}
@@ -217,7 +223,122 @@ public class Numbers {
return BigDecimals.nullToZero(val);
}
// #endregion
// ================================
// #endregion - nullToZero
// ================================
// ================================
// #region - parse
// ================================
/**
* 将字符串转为对应 {@link Short},转换失败时返回 {@code defaultValue}(允许为 {@code null})。
*
* @param str 要转换的字符串
* @param defaultValue 默认值
* @return 转换结果
*/
@Nullable
public static Short parseShort(@Nullable String str, @Nullable Short defaultValue) {
if (StringTools.isBlank(str)) {
return defaultValue;
}
try {
return Short.parseShort(str);
}
catch (NumberFormatException ignore) {
// ignore
}
return defaultValue;
}
/**
* 将字符串转为 {@link Integer},转换失败时返回 {@code defaultValue}(允许为 {@code null})。
*
* @param str 要转换的字符串
* @param defaultValue 默认值
* @return 转换结果
*/
@Nullable
public static Integer parseInteger(@Nullable String str, @Nullable Integer defaultValue) {
if (StringTools.isBlank(str)) {
return defaultValue;
}
try {
return Integer.parseInt(str);
}
catch (NumberFormatException ignore) {
// ignore
}
return defaultValue;
}
/**
* 将字符串转为 {@link Long},转换失败时返回 {@code defaultValue}(允许为 {@code null})。
*
* @param str 要转换的字符串
* @param defaultValue 默认值
* @return 转换结果
*/
@Nullable
public static Long parseLong(@Nullable String str, @Nullable Long defaultValue) {
if (StringTools.isBlank(str)) {
return defaultValue;
}
try {
return Long.parseLong(str);
}
catch (NumberFormatException ignore) {
// ignore
}
return defaultValue;
}
/**
* 将字符串转为 {@link Float},转换失败时返回 {@code defaultValue}(允许为 {@code null})。
*
* @param str 要转换的字符串
* @param defaultValue 默认值
* @return 转换结果
*/
@Nullable
public static Float parseFloat(@Nullable String str, @Nullable Float defaultValue) {
if (StringTools.isBlank(str)) {
return defaultValue;
}
try {
return Float.parseFloat(str);
}
catch (NumberFormatException ignore) {
// ignore
}
return defaultValue;
}
/**
* 将字符串转为 {@link Double},转换失败时返回 {@code defaultValue}(允许为 {@code null})。
*
* @param str 要转换的字符串
* @param defaultValue 默认值
* @return 转换结果
*/
@Nullable
public static Double parseDouble(@Nullable String str, @Nullable Double defaultValue) {
if (StringTools.isBlank(str)) {
return defaultValue;
}
try {
return Double.parseDouble(str);
}
catch (NumberFormatException ignore) {
// ignore
}
return defaultValue;
}
// ================================
// #endregion - parse
// ================================
private Numbers() {
throw new IllegalStateException("Utility class");

View File

@@ -26,6 +26,7 @@ import java.util.Arrays;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
public
@@ -68,9 +69,16 @@ class NumbersTests {
@Test
public void sum_BigIntegerArray_ReturnsCorrectSum() {
BigInteger[] numbers = {new BigInteger("1"), new BigInteger("2"), new BigInteger("3")};
BigInteger[] numbers = {
new BigInteger("1"),
new BigInteger("2"),
null,
new BigInteger("3")
};
BigInteger result = Numbers.sum(numbers);
assertEquals(new BigInteger("6"), result);
assertEquals(BigInteger.ZERO, Numbers.sum(new BigInteger[0]));
}
@Test
@@ -192,6 +200,100 @@ class NumbersTests {
assertEquals(BigDecimal.ZERO, result);
}
/**
* Test for {@link Numbers#parseShort(String, Short)}.
*/
@Test
public void parseShort() {
assertEquals((short) 12345, Numbers.parseShort("12345", (short) 5));
assertEquals((short) 5, Numbers.parseShort("1234.5", (short) 5));
assertEquals((short) 5, Numbers.parseShort("", (short) 5));
assertEquals((short) 5, Numbers.parseShort(null, (short) 5));
assertEquals((short) 12345, Numbers.parseShort("12345", null));
assertNull(Numbers.parseShort("1234.5", null));
assertNull(Numbers.parseShort("", null));
assertNull(Numbers.parseShort(null, null));
}
/**
* Test for {@link Numbers#parseInteger(String, Integer)}.
*/
@Test
public void parseInteger() {
assertEquals(12345, Numbers.parseInteger("12345", 5));
assertEquals(5, Numbers.parseInteger("1234.5", 5));
assertEquals(5, Numbers.parseInteger("", 5));
assertEquals(5, Numbers.parseInteger(null, 5));
assertEquals(12345, Numbers.parseInteger("12345", null));
assertNull(Numbers.parseInteger("1234.5", null));
assertNull(Numbers.parseInteger("", null));
assertNull(Numbers.parseInteger(null, null));
}
/**
* Test for {@link Numbers#parseLong(String, Long)}.
*/
@Test
public void parseLong() {
assertEquals(12345L, Numbers.parseLong("12345", 5L));
assertEquals(5L, Numbers.parseLong("1234.5", 5L));
assertEquals(5L, Numbers.parseLong("", 5L));
assertEquals(5L, Numbers.parseLong(null, 5L));
assertEquals(12345L, Numbers.parseLong("12345", null));
assertNull(Numbers.parseLong("1234.5", null));
assertNull(Numbers.parseLong("", null));
assertNull(Numbers.parseLong(null, null));
}
/**
* Test for {@link Numbers#parseFloat(String, Float)}.
*/
@Test
public void parseFloat() {
assertEquals(1.2345f, Numbers.parseFloat("1.2345", 5.1f));
assertEquals(5.0f, Numbers.parseFloat("a", 5.0f));
assertEquals(5.0f, Numbers.parseFloat("-001Z.2345", 5.0f));
assertEquals(5.0f, Numbers.parseFloat("+001AB.2345", 5.0f));
assertEquals(5.0f, Numbers.parseFloat("001Z.2345", 5.0f));
assertEquals(5.0f, Numbers.parseFloat("", 5.0f));
assertEquals(5.0f, Numbers.parseFloat(null, 5.0f));
assertEquals(1.2345f, Numbers.parseFloat("1.2345", null));
assertNull(Numbers.parseFloat("a", null));
assertNull(Numbers.parseFloat("-001Z.2345", null));
assertNull(Numbers.parseFloat("+001AB.2345", null));
assertNull(Numbers.parseFloat("001Z.2345", null));
assertNull(Numbers.parseFloat("", null));
assertNull(Numbers.parseFloat(null, null));
}
/**
* Test for {@link Numbers#parseDouble(String, Double)}.
*/
@Test
public void parseDouble() {
assertEquals(1.2345d, Numbers.parseDouble("1.2345", 5.1d));
assertEquals(5.0d, Numbers.parseDouble("a", 5.0d));
assertEquals(1.2345d, Numbers.parseDouble("001.2345", 5.1d));
assertEquals(-1.2345d, Numbers.parseDouble("-001.2345", 5.1d));
assertEquals(1.2345d, Numbers.parseDouble("+001.2345", 5.1d));
assertEquals(0d, Numbers.parseDouble("000.00", 5.1d));
assertEquals(5.1d, Numbers.parseDouble("", 5.1d));
assertEquals(5.1d, Numbers.parseDouble((String) null, 5.1d));
assertEquals(1.2345d, Numbers.parseDouble("1.2345", null));
assertEquals(null, Numbers.parseDouble("a", null));
assertEquals(1.2345d, Numbers.parseDouble("001.2345", null));
assertEquals(-1.2345d, Numbers.parseDouble("-001.2345", null));
assertEquals(1.2345d, Numbers.parseDouble("+001.2345", null));
assertEquals(0d, Numbers.parseDouble("000.00", null));
assertEquals(null, Numbers.parseDouble("", null));
assertEquals(null, Numbers.parseDouble((String) null, null));
}
@Test
void test_constructor_isNotAccessible_ThrowsIllegalStateException() {
Constructor<?>[] constructors = Numbers.class.getDeclaredConstructors();