mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
Merge pull request #3007 from zzzj1233/v5-dev
Feat: NumberUtil重载parseXXX方法, 解析失败返回默认值, 代替抛出异常
This commit is contained in:
commit
59470d1669
@ -4586,4 +4586,58 @@ public class CharSequenceUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param str1 字符串1
|
||||||
|
* @param str2 字符串2
|
||||||
|
* @return 字符串1和字符串2的公共前缀
|
||||||
|
*/
|
||||||
|
public static CharSequence commonPrefix(CharSequence str1, CharSequence str2) {
|
||||||
|
|
||||||
|
if (isBlank(str1) || isBlank(str2)) {
|
||||||
|
return EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int minLength = Math.min(str1.length(), str2.length());
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
for (; index < minLength; index++) {
|
||||||
|
|
||||||
|
if (str1.charAt(index) != str2.charAt(index)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return str1.subSequence(0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param str1 字符串1
|
||||||
|
* @param str2 字符串2
|
||||||
|
* @return 字符串1和字符串2的公共后缀
|
||||||
|
*/
|
||||||
|
public static CharSequence commonSuffix(CharSequence str1, CharSequence str2) {
|
||||||
|
|
||||||
|
if (isBlank(str1) || isBlank(str2)) {
|
||||||
|
return EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int str1Index = str1.length() - 1;
|
||||||
|
|
||||||
|
int str2Index = str2.length() - 1;
|
||||||
|
|
||||||
|
for (; str1Index >= 0 && str2Index >= 0; str1Index--, str2Index--) {
|
||||||
|
|
||||||
|
if (str1.charAt(str1Index) != str2.charAt(str2Index)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return str1.subSequence(str1Index + 1, str1.length());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package cn.hutool.core.util;
|
|||||||
import cn.hutool.core.exceptions.UtilException;
|
import cn.hutool.core.exceptions.UtilException;
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.math.Calculator;
|
import cn.hutool.core.math.Calculator;
|
||||||
|
import cn.hutool.core.text.CharSequenceUtil;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
@ -2573,6 +2574,146 @@ public class NumberUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析转换数字字符串为 {@link java.lang.Integer } 规则如下:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* 1、0x开头的视为16进制数字
|
||||||
|
* 2、0开头的忽略开头的0
|
||||||
|
* 3、其它情况按照10进制转换
|
||||||
|
* 4、空串返回0
|
||||||
|
* 5、.123形式返回0(按照小于0的小数对待)
|
||||||
|
* 6、123.56截取小数点之前的数字,忽略小数部分
|
||||||
|
* 7、解析失败返回默认值
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param numberStr 数字字符串,支持0x开头、0开头和普通十进制
|
||||||
|
* @param defaultValue 如果解析失败, 将返回defaultValue, 允许null
|
||||||
|
* @return Integer
|
||||||
|
*/
|
||||||
|
public static Integer parseInt(String numberStr, Integer defaultValue) {
|
||||||
|
if (CharSequenceUtil.isBlank(numberStr)) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return parseInt(numberStr);
|
||||||
|
} catch (NumberFormatException ignore) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析转换数字字符串为 {@link java.lang.Long } 规则如下:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* 1、0x开头的视为16进制数字
|
||||||
|
* 2、0开头的忽略开头的0
|
||||||
|
* 3、其它情况按照10进制转换
|
||||||
|
* 4、空串返回0
|
||||||
|
* 5、.123形式返回0(按照小于0的小数对待)
|
||||||
|
* 6、123.56截取小数点之前的数字,忽略小数部分
|
||||||
|
* 7、解析失败返回默认值
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param numberStr 数字字符串,支持0x开头、0开头和普通十进制
|
||||||
|
* @param defaultValue 如果解析失败, 将返回defaultValue, 允许null
|
||||||
|
* @return Long
|
||||||
|
*/
|
||||||
|
public static Long parseLong(String numberStr, Long defaultValue) {
|
||||||
|
if (CharSequenceUtil.isBlank(numberStr)) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return parseLong(numberStr);
|
||||||
|
} catch (NumberFormatException ignore) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析转换数字字符串为 {@link java.lang.Float } 规则如下:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* 1、0开头的忽略开头的0
|
||||||
|
* 2、空串返回0
|
||||||
|
* 3、其它情况按照10进制转换
|
||||||
|
* 4、.123形式返回0.123(按照小于0的小数对待)
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param numberStr 数字字符串,支持0x开头、0开头和普通十进制
|
||||||
|
* @param defaultValue 如果解析失败, 将返回defaultValue, 允许null
|
||||||
|
* @return Float
|
||||||
|
*/
|
||||||
|
public static Float parseFloat(String numberStr, Float defaultValue) {
|
||||||
|
if (CharSequenceUtil.isBlank(numberStr)) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return parseFloat(numberStr);
|
||||||
|
} catch (NumberFormatException ignore) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析转换数字字符串为 {@link java.lang.Double } 规则如下:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* 1、0开头的忽略开头的0
|
||||||
|
* 2、空串返回0
|
||||||
|
* 3、其它情况按照10进制转换
|
||||||
|
* 4、.123形式返回0.123(按照小于0的小数对待)
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param numberStr 数字字符串,支持0x开头、0开头和普通十进制
|
||||||
|
* @param defaultValue 如果解析失败, 将返回defaultValue, 允许null
|
||||||
|
* @return Double
|
||||||
|
*/
|
||||||
|
public static Double parseDouble(String numberStr, Double defaultValue) {
|
||||||
|
if (CharSequenceUtil.isBlank(numberStr)) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return parseDouble(numberStr);
|
||||||
|
} catch (NumberFormatException ignore) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将指定字符串转换为{@link Number }
|
||||||
|
* 此方法不支持科学计数法
|
||||||
|
*
|
||||||
|
* @param numberStr Number字符串
|
||||||
|
* @param defaultValue 如果解析失败, 将返回defaultValue, 允许null
|
||||||
|
* @return Number对象
|
||||||
|
*/
|
||||||
|
public static Number parseNumber(String numberStr, Number defaultValue) {
|
||||||
|
if (CharSequenceUtil.isBlank(numberStr)) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return parseNumber(numberStr);
|
||||||
|
} catch (NumberFormatException ignore) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* int值转byte数组,使用大端字节序(高位字节在前,低位字节在后)<br>
|
* int值转byte数组,使用大端字节序(高位字节在前,低位字节在后)<br>
|
||||||
* 见:<a href="http://www.ruanyifeng.com/blog/2016/11/byte-order.html">http://www.ruanyifeng.com/blog/2016/11/byte-order.html</a>
|
* 见:<a href="http://www.ruanyifeng.com/blog/2016/11/byte-order.html">http://www.ruanyifeng.com/blog/2016/11/byte-order.html</a>
|
||||||
|
@ -160,4 +160,53 @@ public class CharSequenceUtilTest {
|
|||||||
a = null;
|
a = null;
|
||||||
Assert.assertNull(CharSequenceUtil.trimToNull(a));
|
Assert.assertNull(CharSequenceUtil.trimToNull(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void commonPrefixTest() throws Exception{
|
||||||
|
|
||||||
|
// -------------------------- None match -----------------------
|
||||||
|
|
||||||
|
Assert.assertEquals("", CharSequenceUtil.commonPrefix("", "abc"));
|
||||||
|
Assert.assertEquals("", CharSequenceUtil.commonPrefix(null, "abc"));
|
||||||
|
Assert.assertEquals("", CharSequenceUtil.commonPrefix("abc", null));
|
||||||
|
Assert.assertEquals("", CharSequenceUtil.commonPrefix("abc", ""));
|
||||||
|
|
||||||
|
Assert.assertEquals("", CharSequenceUtil.commonPrefix("azzzj", "bzzzj"));
|
||||||
|
|
||||||
|
Assert.assertEquals("", CharSequenceUtil.commonPrefix("english中文", "french中文"));
|
||||||
|
|
||||||
|
// -------------------------- Matched -----------------------
|
||||||
|
|
||||||
|
Assert.assertEquals("name_", CharSequenceUtil.commonPrefix("name_abc", "name_efg"));
|
||||||
|
|
||||||
|
Assert.assertEquals("zzzj", CharSequenceUtil.commonPrefix("zzzja", "zzzjb"));
|
||||||
|
|
||||||
|
Assert.assertEquals("中文", CharSequenceUtil.commonPrefix("中文english", "中文french"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void commonSuffixTest() throws Exception{
|
||||||
|
|
||||||
|
// -------------------------- None match -----------------------
|
||||||
|
|
||||||
|
Assert.assertEquals("", CharSequenceUtil.commonSuffix("", "abc"));
|
||||||
|
Assert.assertEquals("", CharSequenceUtil.commonSuffix(null, "abc"));
|
||||||
|
Assert.assertEquals("", CharSequenceUtil.commonSuffix("abc", null));
|
||||||
|
Assert.assertEquals("", CharSequenceUtil.commonSuffix("abc", ""));
|
||||||
|
|
||||||
|
Assert.assertEquals("", CharSequenceUtil.commonSuffix("zzzja", "zzzjb"));
|
||||||
|
|
||||||
|
Assert.assertEquals("", CharSequenceUtil.commonSuffix("中文english", "中文Korean"));
|
||||||
|
|
||||||
|
// -------------------------- Matched -----------------------
|
||||||
|
|
||||||
|
Assert.assertEquals("_name", CharSequenceUtil.commonSuffix("abc_name", "efg_name"));
|
||||||
|
|
||||||
|
Assert.assertEquals("zzzj", CharSequenceUtil.commonSuffix("abczzzj", "efgzzzj"));
|
||||||
|
|
||||||
|
Assert.assertEquals("中文", CharSequenceUtil.commonSuffix("english中文", "Korean中文"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,12 @@ import java.math.BigInteger;
|
|||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static cn.hutool.core.util.NumberUtil.parseDouble;
|
||||||
|
import static cn.hutool.core.util.NumberUtil.parseFloat;
|
||||||
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.hamcrest.CoreMatchers.nullValue;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link NumberUtil} 单元测试类
|
* {@link NumberUtil} 单元测试类
|
||||||
*
|
*
|
||||||
@ -296,6 +302,23 @@ public class NumberUtilTest {
|
|||||||
Assert.assertEquals(0, v1);
|
Assert.assertEquals(0, v1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseIntTest4() {
|
||||||
|
|
||||||
|
// -------------------------- Parse failed -----------------------
|
||||||
|
|
||||||
|
assertThat(NumberUtil.parseInt("abc", null), nullValue());
|
||||||
|
|
||||||
|
assertThat(NumberUtil.parseInt("abc", 456), equalTo(456));
|
||||||
|
|
||||||
|
// -------------------------- Parse success -----------------------
|
||||||
|
|
||||||
|
assertThat(NumberUtil.parseInt("123.abc", 789), equalTo(123));
|
||||||
|
|
||||||
|
assertThat(NumberUtil.parseInt("123.3", null), equalTo(123));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = NumberFormatException.class)
|
@Test(expected = NumberFormatException.class)
|
||||||
public void parseNumberTest4(){
|
public void parseNumberTest4(){
|
||||||
// issue#I5M55F
|
// issue#I5M55F
|
||||||
@ -324,6 +347,29 @@ public class NumberUtilTest {
|
|||||||
Assert.assertTrue(number instanceof BigDecimal);
|
Assert.assertTrue(number instanceof BigDecimal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseNumberTest3(){
|
||||||
|
|
||||||
|
// -------------------------- Parse failed -----------------------
|
||||||
|
|
||||||
|
assertThat(NumberUtil.parseNumber("abc", null), nullValue());
|
||||||
|
|
||||||
|
assertThat(NumberUtil.parseNumber(StrUtil.EMPTY, null), nullValue());
|
||||||
|
|
||||||
|
assertThat(NumberUtil.parseNumber(StrUtil.repeat(StrUtil.SPACE, 10), null), nullValue());
|
||||||
|
|
||||||
|
assertThat(NumberUtil.parseNumber("abc", 456).intValue(), equalTo(456));
|
||||||
|
|
||||||
|
// -------------------------- Parse success -----------------------
|
||||||
|
|
||||||
|
assertThat(NumberUtil.parseNumber("123.abc", 789).intValue(), equalTo(123));
|
||||||
|
|
||||||
|
assertThat(NumberUtil.parseNumber("123.3", null).doubleValue(), equalTo(123.3D));
|
||||||
|
|
||||||
|
assertThat(NumberUtil.parseNumber("0.123.3", null).doubleValue(), equalTo(0.123D));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parseHexNumberTest() {
|
public void parseHexNumberTest() {
|
||||||
// 千位分隔符去掉
|
// 千位分隔符去掉
|
||||||
@ -362,6 +408,69 @@ public class NumberUtilTest {
|
|||||||
Assert.assertEquals(0, number);
|
Assert.assertEquals(0, number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseLongTest2() {
|
||||||
|
|
||||||
|
// -------------------------- Parse failed -----------------------
|
||||||
|
|
||||||
|
Long v1 = NumberUtil.parseLong(null, null);
|
||||||
|
assertThat(v1, nullValue());
|
||||||
|
|
||||||
|
Long v2 = NumberUtil.parseLong(StrUtil.EMPTY, null);
|
||||||
|
assertThat(v2, nullValue());
|
||||||
|
|
||||||
|
Long v3 = NumberUtil.parseLong("L3221", 1233L);
|
||||||
|
assertThat(v3, equalTo(1233L));
|
||||||
|
|
||||||
|
// -------------------------- Parse success -----------------------
|
||||||
|
|
||||||
|
Long v4 = NumberUtil.parseLong("1233L", null);
|
||||||
|
assertThat(v4, equalTo(1233L));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseFloatTest() throws Exception {
|
||||||
|
|
||||||
|
// -------------------------- Parse failed -----------------------
|
||||||
|
|
||||||
|
assertThat(parseFloat("abc", null), nullValue());
|
||||||
|
|
||||||
|
assertThat(parseFloat("a123.33", null), nullValue());
|
||||||
|
|
||||||
|
assertThat(parseFloat("..123", null), nullValue());
|
||||||
|
|
||||||
|
assertThat(parseFloat(StrUtil.EMPTY, 1233F), equalTo(1233F));
|
||||||
|
|
||||||
|
// -------------------------- Parse success -----------------------
|
||||||
|
|
||||||
|
assertThat(parseFloat("123.33a", null), equalTo(123.33F));
|
||||||
|
|
||||||
|
assertThat(parseFloat(".123", null), equalTo(0.123F));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseDoubleTest() throws Exception {
|
||||||
|
|
||||||
|
// -------------------------- Parse failed -----------------------
|
||||||
|
|
||||||
|
assertThat(parseDouble("abc", null), nullValue());
|
||||||
|
|
||||||
|
assertThat(parseDouble("a123.33", null), nullValue());
|
||||||
|
|
||||||
|
assertThat(parseDouble("..123", null), nullValue());
|
||||||
|
|
||||||
|
assertThat(parseDouble(StrUtil.EMPTY, 1233D), equalTo(1233D));
|
||||||
|
|
||||||
|
// -------------------------- Parse success -----------------------
|
||||||
|
|
||||||
|
assertThat(parseDouble("123.33a", null), equalTo(123.33D));
|
||||||
|
|
||||||
|
assertThat(parseDouble(".123", null), equalTo(0.123D));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void factorialTest(){
|
public void factorialTest(){
|
||||||
long factorial = NumberUtil.factorial(0);
|
long factorial = NumberUtil.factorial(0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user