
导读
数字类型的判断是项目里常见的场景,相比一大串的非空,instanceof 以及大于小于0的判断,我更倾向于使用工具类 StringUtils 或者 正则表达式 来实现功能,追求代码的简洁和高效。
你可能需要的博客:
- 正则表达式预编译功能的正确使用
- Java 正则表达式:语法讲解和常用表达式汇总
正文
一、StringUtils 方法
isNumeric() 和 isNumericSpace() 都属于 StringUtils,区别也就在字面意思里:对 Space(空格)的处理方式不用。
使用 StringUtils 类,需要在 pom.xml 中引入“commons-lang3”依赖:
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.10</version></dependency>
1. StringUtils.isNumeric()
目的:用来判断传入字符串是否为正整数。
- 方法展示
@Testvoid test_isNumeric(){System.out.println("正整数:" + StringUtils.isNumeric("123")); // trueSystem.out.println("零:" + StringUtils.isNumeric("0")); // trueSystem.out.println("负整数:" + StringUtils.isNumeric("-123")); // falseSystem.out.println("小数:" + StringUtils.isNumeric("1.23")); // falseSystem.out.println("null:" + StringUtils.isNumeric(null)); // falseSystem.out.println("空格:" + StringUtils.isNumeric(" ")); // falseSystem.out.println("空字符串:" + StringUtils.isNumeric("")); // falseSystem.out.println("数字带空格:" + StringUtils.isNumeric("1 2 3")); // false}
- StringUtils.isNumeric() 源码
isNumeric() 会遍历 CharSequence 字符并逐一校验,所以就需要参数字符串的每一位都满足【十进制数字】这一规则,所以,像“-123”或“+123”这样认知上为数字的字符串验证结果是 False。
/** StringUtils.isNumeric() 源码 */public static boolean isNumeric(CharSequence cs) {// 1. 校验:'',空和nullif (isEmpty(cs)) {return false;} else {int sz = cs.length();for(int i = 0; i < sz; ++i) {// 2. 校验:判断字符的一般类别是否为【十进制数字】if (!Character.isDigit(cs.charAt(i))) {return false;}}return true;}}
如果进一步 DeBug 进入 Character.isDigit() 方法,会发现 isDigit() 属于 java.lang.Character,也就是说:isNumeric() 归根结底用的还是 Java 自带的字符判断方法。
/** 当前方法属于 java.lang.Character */ public static boolean isDigit(char ch) {return isDigit((int)ch);}
进一步 DeBug 进入 isDigit() , 核心代码是 Character.getType() 方法,它的作用就是:判断字符的一般类别是否为【十进制数字】(十进制数字返回9,其他类型自己看源码)。
/** 当前方法属于 java.lang.Character */public static boolean isDigit(int codePoint) {// getType() 目的是获取 codePoint 的类型// Character.DECIMAL_DIGIT_NUMBER = 9return getType(codePoint) == Character.DECIMAL_DIGIT_NUMBER;}
2. StringUtils.isNumericSpace()
目的:用来判断传入字符串是否为正整数,字符串里的空格不影响结果。
- 方法展示
@Testvoid test_isNumericSpace(){System.out.println("正整数:" + StringUtils.isNumericSpace("123")); // trueSystem.out.println("零:" + StringUtils.isNumericSpace("0")); // trueSystem.out.println("负整数:" + StringUtils.isNumericSpace("-123")); // falseSystem.out.println("小数:" + StringUtils.isNumericSpace("1.23")); // falseSystem.out.println("null:" + StringUtils.isNumericSpace(null)); // falseSystem.out.println("空格:" + StringUtils.isNumericSpace(" ")); // trueSystem.out.println("空字符串:" + StringUtils.isNumericSpace("")); // trueSystem.out.println("数字带空格:" + StringUtils.isNumericSpace("1 2 3")); // true}
- StringUtils.isNumericSpace() 源码
isNumericSpace()与isNumeric()的区别在于,isNumericSpace() 对空格以及空字符串的处理结果也为 True,就算是字符串内部的空格也会自动忽略掉,这些改变在源码里可以清晰的看出差别。
/** StringUtils.isNumericSpace() 源码 */public static boolean isNumericSpace(CharSequence cs) {// 1. 这里没有 isEmpty() 判空,只校验了 nullif (cs == null) {return false;} else {int sz = cs.length();for(int i = 0; i < sz; ++i) {// 2. 这里排除了“空格”的情况,认为不为正整数且同时不为''时,才返回 Falseif (!Character.isDigit(cs.charAt(i)) && cs.charAt(i) != ' ') {return false;}}return true;}}
其他部分源码与分析与isNumeric()一脉相承。
二、正则表达式
StringUtils 的方法有自己的局限性,它只能判断正整数,其他的数字类型,如:负整数,浮点数...,使用正则表达式是常用的手段。
- 预编译的正则写法
// regexRule 是正则规则private static final Pattern pattern = Pattern.compile(regexRule);@Testvoid test_pattern(){Matcher mat = pattern.matcher("-123");System.out.println("正则匹配结果:" + mat);}
- 数字有关的正则表达式
| 说明 | 正则表达式 |
|---|---|
| 非负整数(正整数 + 0) | ^\d+$ |
| 正整数 | ^[0-9]*[1-9][0-9]*$ |
| 非正整数(负整数 + 0) | ^((-\d+)|(0+))$ |
| 负整数 | ^-[0-9]*[1-9][0-9]*$ |
| 浮点数 | ^(-?\d+)(\.\d+)?$ |
| 非负浮点数(正浮点数 + 0) | ^\d+(\.\d+)?$ |
| 非正浮点数(负浮点数 + 0) | ^((-\d+(\.\d+)?)|(0+(\.0+)?))$ |
| ...... |

















