其他分享
首页 > 其他分享> > StringUtils.isNumeric判断是否是数字字符串

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