在本文中,我们将通过几种方法检查 String 在 Java 中是否为数值型?
使用内置方法
最简单的方法是使用 Java 中的内置方法,例如Double.parseDouble(String str)。如果字符串参数是数字并且可以解析为数字,则此方法将返回一个双精度值。 如果没有,它会抛出异常。
下面是一些内置方法:
- Integer.parseInt(String)
- Float.parseFloat(String)
- Double.parseDouble(String)
- Long.parseLong(String)
- new BigInteger(String)
如果这些方法没有抛出任何NumberFormatException,那么就意味着解析成功了,而且String是数字的:
public class Numeric { |
在上面的程序中,我们有一个名为 string 的String,它包含要检查的字符串。我们还有一个布尔值数字,用于存储最终结果是否为数字。
要检查字符串是否仅包含数字,在 try 块中,我们使用Double的parseDouble()方法将字符串转换为Double。
如果它抛出错误(即NumberFormatException 错误),则意味着该字符串不是数字并且 numeric 设置为false。否则,它是一个数字。
但是,如果要检查是否有多个字符串,则需要将其更改为函数。而且,逻辑基于抛出异常,这可能非常昂贵。
相反,我们可以使用正则表达式的强大功能来检查字符串是否为数字,如下所示。
使用 NumberFormat.parse() 方法
另一种方法是使用NumberFormat.parse()方法来解析给定的字符串。与方法Double.parseDouble()不同,它不会抛出异常;如果没有可以解析的对象,则索引保持不变。
import java.text.NumberFormat; |
使用Guava
在Guava中,你可以使用Double.tryParse()方法将指定的字符串解析为一个双数。然而,与Double.parseDouble()方法不同的是,如果解析失败,它会返回null而不是抛出一个异常。有效的输入正是Double.valueOf(String s)所接受的,除了不允许前导和尾部的空白。
import com.google.common.primitives.Doubles; |
使用正则表达式
另一种方法是使用正则表达式。下面提供了基于正则的解决方案,使用正则表达式[-+]?\d*\.?\d+来处理负数和小数。请注意,\d只与[0-9]范围内的数字相匹配,对于其他语言的数字会失败。
我们可以写正则表达式来匹配我们的字符串,并判断它们是否是数字。我们将使用字符串的 matches() 方法来比较字符串的数字和正则表达式。我们将使用正则表达式"-?\\d+(\\.\d+)? "来匹配字符串。让我们试着理解这个正则表达式。
public class Numeric { |
在上面的程序中,我们没有使用try-catch块,而是使用regex来检查字符串是否为数字。这是用String的matches()方法完成的。
在matches()方法中、
- -? - 这一部分确定给定的数字是否为负数,破折号"-"搜索字面上的破折号,问号"?"标志着它的存在是一个可选的。
- \\d+ 检查字符串必须至少有1个或更多的数字(\\d)。
- (\.\d+)?- regex的这一部分是用来识别浮动的数字。这里我们搜索的是一个或多个数字,后面跟着一个句号。结尾处的问号表示小括号内的整个regex部分是可选的,因为一个数字可能不是小数。
我创建了一个简单的方法来检查传入的字符串是否为数字:
public class StringTest { |
isNumeric()方法接受一个字符串作为参数。首先,它检查它是否为空。然后,我们使用matches()方法来检查它是否包含数字0到9和句点字符。
这是检查数字值的一个简单方法。你可以根据你的使用情况,编写或在谷歌上搜索更高级的正则表达式来捕获数字。
内建式与正则表达式的性能
一般来说,Regex版本的性能会比使用内置方法更好。这取决于JVM,但通常这是因为内置方法依赖于抛出和捕获异常,这很昂贵。
在我的机器上,10,000个样本(所有参数都是有效的整数)给出了以下的基准:
Built-in took 15 ms |
如果我引入错误的样本,即10000个样本中的每2个都不是有效的数字,那么内置的数字就会变得更糟,因为有大量的异常处理在进行。
Built-in took 35 ms |
使用Apache Commons库检查一个字符串是否为数字
Apache Commons库提供了一些不同的方法,可以直接用来检查一个字符串是否为数字。让我们分别来看看它们中的每一个。
1、NumberUtils.isCreatable() 方法
isCreatable()是NumberUtils类的一个静态方法,用于检查一个给定的字符串是否是有效的Java数字。一个空的、空的或空白的字符串将返回false。
这个方法接受:
- 以0x或0X开头的十六进制数
- 以0开头的八进制数字
- 科学符号(例如1.05e-10)。
- 标有类型限定符的数字(例如1L或2.2d)。
import org.apache.commons.lang3.math.NumberUtils; |
2、NumberUtils.isParsable()方法
NumberUtils.isParsable(String)是NumberUtils类的一个静态方法,用于检查一个给定的String是否是可解析的。
可解析的数字是那些被任何解析方法成功解析的数字,比如Integer.parseInt(String), Long.parseLong(String), Float.parseFloat(String) 或者Double.parseDouble(String)。
与NumberUtils.isCreatable()不同的是,这个方法不接受十六进制数字、科学符号或以任何类型的限定符(如'f'、'F'、'd'、'D'、'l'或'L')结尾的字符串。
3、StringUtils.isNumeric(CharSequence)
StringUtils.isNumeric(CharSequence)检查CharSequence是否只包含Unicode数字。这个方法可以接受任何语言的unicode数字。它不能接受正负符号或小数点,因为小数点不被认为是Unicode数字。
4、StringUtils.isNumericSpace(CharSequence)
StringUtils.isNumericSpace(CharSequence)严格检查Unicode数字和/或空格。这与StringUtils.isNumeric()相同,只是它也接受空格,而且不仅是前导和后导的空格,如果它们在数字之间也接受。