Java中最优雅的isNumeric()解决方案是什么?

16

我正在将一小段PHP代码移植到Java中,我依赖于函数is_numeric($x)来确定$x是否为数字。 在Java中似乎没有等效的函数,并且我对迄今为止找到的解决方案不满意。

我倾向于在这里找到的正则表达式解决方案:http://rosettacode.org/wiki/Determine_if_a_string_is_numeric

我应该使用哪种方法,为什么?


“numeric” 是什么意思?您是否需要 PHP 的精确定义?请参考 http://php.net/manual/en/function.is-numeric.php。 - Mark Byers
不必完全匹配PHP定义,但如果能匹配的话会很好,因为我知道我的算法可以与该函数一起使用。 - Doug
7个回答

16
注意,PHP 的 isNumeric() 函数可以正确地确定十六进制和科学计数法是数字,而你提供的正则表达式方法无法做到这一点。
一个选项,特别是如果你已经在使用 Apache Commons 库,是使用 Commons-Lang 中的 NumberUtils.isNumber()。它将处理与 PHP 函数相同的情况。

那个函数似乎正好做我想要的事情,但是我没有使用apache commons库 :( - Doug
3
@Doug Commons Lang 几乎存在于每个 Java 程序中,它在很多方面都非常有用。下载并将其添加到类路径中,您会感到非常高兴。 - TheLQ
2
决定是否添加库总是很棘手,尤其是当你只需要其中的一小部分时。但是如果你深入研究,你会发现Apache Commons Lang可以提供其他你会用到的东西——它基本上是“Java应该内置但却没有的东西”。我强烈推荐《The Common Java Cookbook》(http://www.discursive.com/books/cjcook/reference/book-cjcook.html),它提供了许多使用Apache库的技巧。 - Jacob Mattison

4

你是否考虑过使用StringUtils库?它有一个isNumeric()函数,可能是你需要的。请注意,空字符串将被评估为true。


1
Commons 的 isNumeric 函数只会寻找整数,例如包含小数点的数字将被拒绝,而科学计数法则更不被接受。请参考我的答案,查找不同的 Commons 函数来达到你所需要的目标。 - Jacob Mattison
@JacobM:确实,我看到了这个NumberUtils,并准备更新我的答案,但当我看到你的评论时就放弃了。 - Fanny H.

2

您可以选择使用正则表达式。

   if (theString.matches("((-|\\+)?[0-9]+(\\.[0-9]+)?)+")))
     return true;

    return false;

那个最后的 + 是什么意思?"-7.0-4.2"将返回true到这个表达式。 - Doug

2
通常在字符串中包含数字是一个不好的主意。如果你想使用这个数字,那么解析它并将其用作数字。你不应该需要“检查”它是否为数字,要么你想将其用作数字,要么不想。
如果你需要转换它,那么你可以使用从Integer.parseInt(String)到BigDecimal(String)的每个解析器。
如果你只需要检查内容是否可以被视为数字,那么你可以使用正则表达式。
如果你的字符串可能包含浮点数,则不要使用parseInt。

3
通常,如果有人在寻找一个isNumeric方法,那么他们肯定没有把这个可怜的数字自己放到字符串里 ;) - Jostikas

1
你尝试过使用Integer.parseInt()吗?(我不确定方法名,但是Integer类有一个从字符串创建Integer对象的方法)。或者如果你需要处理非整数数字,Double对象也有类似的方法可用。如果这些方法失败了,就会抛出异常。
如果你需要解析非常大的数字(比int/double还要大),而且不需要精确的值,那么一个简单的基于正则表达式的方法可能就足够了。

2
如果您预计有相当比例的字符串不是数字,使用抛出异常来查找它们既不是好的实践(非数字字符串并不是“异常情况”),也可能会导致性能问题。 - Jacob Mattison
这是正确的。它取决于使用场景。 - Zoltán Ujhelyi

0
在强类型语言中,一个泛型的isNumeric(String num)方法并不是非常有用。13214384348934918434441是数字,但它无法适应大多数类型。许多适合它的类型将不会返回相同的值。
正如Colin所指出的那样,在应用程序中使用字符串来存储数字并不推荐。isNumberic函数只适用于接口方法上的输入数据。这些方法应该比isNumeric具有更精确的定义。其他人已经提供了各种解决方案。正则表达式可以用于同时测试许多条件,包括字符串长度。

0
只需使用以下代码: if((x instanceof Number) //如果还要检查可解析数字 || (x instanceof String && x.matches("((-|\+)?[0-9]+(\.[0-9]+)?)+")) ){ ... } //---所有数值类型,包括BigDecimal都扩展自Number

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接