在解析字符串之前,如何检查它是否是一个数字?
当前回答
Java 8流,lambda表达式,函数接口
处理的所有情况(字符串空,字符串空等)
String someString = null; // something="", something="123abc", something="123123"
boolean isNumeric = Stream.of(someString)
.filter(s -> s != null && !s.isEmpty())
.filter(Pattern.compile("\\D").asPredicate().negate())
.mapToLong(Long::valueOf)
.boxed()
.findAny()
.isPresent();
其他回答
这里有两种可能有效的方法。(不使用异常)。 注意:Java默认是值传递,String的值是String对象数据的地址。 所以,当你在做
stringNumber = stringNumber.replaceAll(" ", "");
您已将输入值更改为没有空格。 如果你愿意,可以去掉这条线。
private boolean isValidStringNumber(String stringNumber)
{
if(stringNumber.isEmpty())
{
return false;
}
stringNumber = stringNumber.replaceAll(" ", "");
char [] charNumber = stringNumber.toCharArray();
for(int i =0 ; i<charNumber.length ;i++)
{
if(!Character.isDigit(charNumber[i]))
{
return false;
}
}
return true;
}
这里是另一个方法,以防你想允许浮动 据称,这种方法允许表单中的数字通过 1123123123123123年.123 我刚做好,我想还需要进一步测试以确保它能正常工作。
private boolean isValidStringTrueNumber(String stringNumber)
{
if(stringNumber.isEmpty())
{
return false;
}
stringNumber = stringNumber.replaceAll(" ", "");
int countOfDecimalPoint = 0;
boolean decimalPointPassed = false;
boolean commaFound = false;
int countOfDigitsBeforeDecimalPoint = 0;
int countOfDigitsAfterDecimalPoint =0 ;
int commaCounter=0;
int countOfDigitsBeforeFirstComma = 0;
char [] charNumber = stringNumber.toCharArray();
for(int i =0 ; i<charNumber.length ;i++)
{
if((commaCounter>3)||(commaCounter<0))
{
return false;
}
if(!Character.isDigit(charNumber[i]))//Char is not a digit.
{
if(charNumber[i]==',')
{
if(decimalPointPassed)
{
return false;
}
commaFound = true;
//check that next three chars are only digits.
commaCounter +=3;
}
else if(charNumber[i]=='.')
{
decimalPointPassed = true;
countOfDecimalPoint++;
}
else
{
return false;
}
}
else //Char is a digit.
{
if ((commaCounter>=0)&&(commaFound))
{
if(!decimalPointPassed)
{
commaCounter--;
}
}
if(!commaFound)
{
countOfDigitsBeforeFirstComma++;
}
if(!decimalPointPassed)
{
countOfDigitsBeforeDecimalPoint++;
}
else
{
countOfDigitsAfterDecimalPoint++;
}
}
}
if((commaFound)&&(countOfDigitsBeforeFirstComma>3))
{
return false;
}
if(countOfDecimalPoint>1)
{
return false;
}
if((decimalPointPassed)&&((countOfDigitsBeforeDecimalPoint==0)||(countOfDigitsAfterDecimalPoint==0)))
{
return false;
}
return true;
}
如果字符串可能包含小数,则可以使用BigDecimal:
try {
new java.math.BigInteger(testString);
} catch(NumberFormatException e) {
throw new RuntimeException("Not a valid number");
}
正如@CraigTP在他的精彩回答中提到的,我也有类似的性能问题,使用exception来测试字符串是否是数值。因此,我最终分割字符串并使用java.lang.Character.isDigit()。
public static boolean isNumeric(String str)
{
for (char c : str.toCharArray())
{
if (!Character.isDigit(c)) return false;
}
return true;
}
根据Javadoc, Character.isDigit(char)将正确识别非拉丁数字。在性能方面,我认为简单的N次比较(其中N是字符串中的字符数)在计算上比正则表达式匹配更有效。
更新:正如Jean-François Corbett在评论中指出的那样,上面的代码只验证正整数,这涵盖了我的大部分用例。下面是更新后的代码,它根据系统中使用的默认区域设置正确验证十进制数,假设十进制分隔符只在字符串中出现一次。
public static boolean isStringNumeric( String str )
{
DecimalFormatSymbols currentLocaleSymbols = DecimalFormatSymbols.getInstance();
char localeMinusSign = currentLocaleSymbols.getMinusSign();
if ( !Character.isDigit( str.charAt( 0 ) ) && str.charAt( 0 ) != localeMinusSign ) return false;
boolean isDecimalSeparatorFound = false;
char localeDecimalSeparator = currentLocaleSymbols.getDecimalSeparator();
for ( char c : str.substring( 1 ).toCharArray() )
{
if ( !Character.isDigit( c ) )
{
if ( c == localeDecimalSeparator && !isDecimalSeparatorFound )
{
isDecimalSeparatorFound = true;
continue;
}
return false;
}
}
return true;
}
不要使用异常来验证你的值。 使用Util库代替apache NumberUtils:
NumberUtils.isNumber(myStringValue);
编辑:
请注意,如果字符串以0开头,NumberUtils将把您的值解释为十六进制。
NumberUtils.isNumber("07") //true
NumberUtils.isNumber("08") //false
使用IntStream并行检查非常长的字符串
在Java 8中,以下测试给定字符串的所有字符是否都在'0'到'9'之间。注意空字符串是被接受的:
string.chars().unordered().parallel().allMatch( i -> '0' <= i && '9' >= i )
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- Printf与std::字符串?
- 在Jar文件中运行类
- 带参数的可运行?
- 不区分大小写的“in”
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- 如何在PHP中截断字符串最接近于一定数量的字符?
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作