StringUtils.isNumeric判断是否是数字字符串
作者:互联网
StringUtils.isNumeric判断是否是数字字符串
org.apache.commons.lang3.StringUtils
字符串工具类StringUtils能够很方便的处理Java字符串问题,简直是Java字符串的一大法宝
可以记录下常用的功能,即便对于字符串对象为null,也是轻松处理
IsEmpty/IsBlank - checks if a String contains text
Trim/Strip - removes leading and trailing whitespace
Equals/Compare - compares two strings null-safe
startsWith - check if a String starts with a prefix null-safe
endsWith - check if a String ends with a suffix null-safe
IndexOf/LastIndexOf/Contains - null-safe index-of checks
IndexOfAny/LastIndexOfAny/IndexOfAnyBut/LastIndexOfAnyBut - index-of any of a set of Strings
ContainsOnly/ContainsNone/ContainsAny - does String contains only/none/any of these characters
Substring/Left/Right/Mid - null-safe substring extractions
SubstringBefore/SubstringAfter/SubstringBetween - substring extraction relative to other strings
Split/Join - splits a String into an array of substrings and vice versa
Remove/Delete - removes part of a String
Replace/Overlay - Searches a String and replaces one String with another
Chomp/Chop - removes the last part of a String
UpperCase/LowerCase/SwapCase/Capitalize/Uncapitalize - changes the case of a String
CountMatches - counts the number of occurrences of one String in another
IsAlpha/IsNumeric/IsWhitespace/IsAsciiPrintable - checks the characters in a String
DefaultString - protects against a null input String
Reverse/ReverseDelimited - reverses a String
StringUtils.isNumeric
其中需要注意的是 StringUtils.isNumeric 在判断是否是数字字符串的时候,无法包含所有情况
官网上也有实例说明,对于含有特殊符号的字符串,是无法解析的
StringUtils.isNumeric(null) = false
StringUtils.isNumeric("") = false
StringUtils.isNumeric(" ") = false
StringUtils.isNumeric("123") = true
StringUtils.isNumeric("१२३") = true
StringUtils.isNumeric("12 3") = false
StringUtils.isNumeric("ab2c") = false
StringUtils.isNumeric("12-3") = false
StringUtils.isNumeric("12.3") = false
StringUtils.isNumeric("-123") = false
StringUtils.isNumeric("+123") = false
看其源码就知道,它这里仅仅对每个字符做了数字判断
public static boolean isNumeric(String str) {
if (str == null) {
return false;
} else {
int sz = str.length();
for(int i = 0; i < sz; ++i) {
if (!Character.isDigit(str.charAt(i))) {
return false;
}
}
return true;
}
}
完整的判断
如果要完整判断一个字符串是不是数字字符串,最方便的就是借助math中的BigDecimal类,如果不是数字就会跑出异常,这时候捕获就可以判定为非数字
如果确定输入数据不包含正负号、小数点的话,可以直接使用,会提高很多性能,否则需要借助BigDecimal类来完整判别
import java.math.BigDecimal;
public static boolean isNumeric(String str) {
try {
new BigDecimal(str);
} catch (Exception e) {
return false;
}
return true;
}
构造函数源码
// BigDecimal类的相应的构造函数源码,可以看到,它考虑到了很多情况,非常经典,值得好好学习
public BigDecimal(char[] in, int offset, int len, MathContext mc) {
// protect against huge length.
if (offset + len > in.length || offset < 0)
throw new NumberFormatException("Bad offset or len arguments for char[] input.");
// This is the primary string to BigDecimal constructor; all
// incoming strings end up here; it uses explicit (inline)
// parsing for speed and generates at most one intermediate
// (temporary) object (a char[] array) for non-compact case.
// Use locals for all fields values until completion
int prec = 0; // record precision value
int scl = 0; // record scale value
long rs = 0; // the compact value in long
BigInteger rb = null; // the inflated value in BigInteger
// use array bounds checking to handle too-long, len == 0,
// bad offset, etc.
try {
// handle the sign
boolean isneg = false; // assume positive
if (in[offset] == '-') {
isneg = true; // leading minus means negative
offset++;
len--;
} else if (in[offset] == '+') { // leading + allowed
offset++;
len--;
}
// should now be at numeric part of the significand
boolean dot = false; // true when there is a '.'
long exp = 0; // exponent
char c; // current character
boolean isCompact = (len <= MAX_COMPACT_DIGITS);
// integer significand array & idx is the index to it. The array
// is ONLY used when we can't use a compact representation.
int idx = 0;
if (isCompact) {
// First compact case, we need not to preserve the character
// and we can just compute the value in place.
for (; len > 0; offset++, len--) {
c = in[offset];
if ((c == '0')) { // have zero
if (prec == 0)
prec = 1;
else if (rs != 0) {
rs *= 10;
++prec;
} // else digit is a redundant leading zero
if (dot)
++scl;
} else if ((c >= '1' && c <= '9')) { // have digit
int digit = c - '0';
if (prec != 1 || rs != 0)
++prec; // prec unchanged if preceded by 0s
rs = rs * 10 + digit;
if (dot)
++scl;
} else if (c == '.') { // have dot
// have dot
if (dot) // two dots
throw new NumberFormatException();
dot = true;
} else if (Character.isDigit(c)) { // slow path
int digit = Character.digit(c, 10);
if (digit == 0) {
if (prec == 0)
prec = 1;
else if (rs != 0) {
rs *= 10;
++prec;
} // else digit is a redundant leading zero
} else {
if (prec != 1 || rs != 0)
++prec; // prec unchanged if preceded by 0s
rs = rs * 10 + digit;
}
if (dot)
++scl;
} else if ((c == 'e') || (c == 'E')) {
exp = parseExp(in, offset, len);
// Next test is required for backwards compatibility
if ((int) exp != exp) // overflow
throw new NumberFormatException();
break; // [saves a test]
} else {
throw new NumberFormatException();
}
}
if (prec == 0) // no digits found
throw new NumberFormatException();
// Adjust scale if exp is not zero.
if (exp != 0) { // had significant exponent
scl = adjustScale(scl, exp);
}
rs = isneg ? -rs : rs;
int mcp = mc.precision;
int drop = prec - mcp; // prec has range [1, MAX_INT], mcp has range [0, MAX_INT];
// therefore, this subtract cannot overflow
if (mcp > 0 && drop > 0) { // do rounding
while (drop > 0) {
scl = checkScaleNonZero((long) scl - drop);
rs = divideAndRound(rs, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode);
prec = longDigitLength(rs);
drop = prec - mcp;
}
}
} else {
char coeff[] = new char[len];
for (; len > 0; offset++, len--) {
c = in[offset];
// have digit
if ((c >= '0' && c <= '9') || Character.isDigit(c)) {
// First compact case, we need not to preserve the character
// and we can just compute the value in place.
if (c == '0' || Character.digit(c, 10) == 0) {
if (prec == 0) {
coeff[idx] = c;
prec = 1;
} else if (idx != 0) {
coeff[idx++] = c;
++prec;
} // else c must be a redundant leading zero
} else {
if (prec != 1 || idx != 0)
++prec; // prec unchanged if preceded by 0s
coeff[idx++] = c;
}
if (dot)
++scl;
continue;
}
// have dot
if (c == '.') {
// have dot
if (dot) // two dots
throw new NumberFormatException();
dot = true;
continue;
}
// exponent expected
if ((c != 'e') && (c != 'E'))
throw new NumberFormatException();
exp = parseExp(in, offset, len);
// Next test is required for backwards compatibility
if ((int) exp != exp) // overflow
throw new NumberFormatException();
break; // [saves a test]
}
// here when no characters left
if (prec == 0) // no digits found
throw new NumberFormatException();
// Adjust scale if exp is not zero.
if (exp != 0) { // had significant exponent
scl = adjustScale(scl, exp);
}
// Remove leading zeros from precision (digits count)
rb = new BigInteger(coeff, isneg ? -1 : 1, prec);
rs = compactValFor(rb);
int mcp = mc.precision;
if (mcp > 0 && (prec > mcp)) {
if (rs == INFLATED) {
int drop = prec - mcp;
while (drop > 0) {
scl = checkScaleNonZero((long) scl - drop);
rb = divideAndRoundByTenPow(rb, drop, mc.roundingMode.oldMode);
rs = compactValFor(rb);
if (rs != INFLATED) {
prec = longDigitLength(rs);
break;
}
prec = bigDigitLength(rb);
drop = prec - mcp;
}
}
if (rs != INFLATED) {
int drop = prec - mcp;
while (drop > 0) {
scl = checkScaleNonZero((long) scl - drop);
rs = divideAndRound(rs, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode);
prec = longDigitLength(rs);
drop = prec - mcp;
}
rb = null;
}
}
}
} catch (ArrayIndexOutOfBoundsException e) {
throw new NumberFormatException();
} catch (NegativeArraySizeException e) {
throw new NumberFormatException();
}
this.scale = scl;
this.precision = prec;
this.intCompact = rs;
this.intVal = rb;
}
参考
标签:String,rs,drop,是否是,prec,isNumeric,StringUtils 来源: https://blog.csdn.net/whgyxy/article/details/97015820