【发布时间】:2020-04-18 02:08:40
【问题描述】:
Apache 的 StringUtils.isNumeric() 方法规范说:
检查字符串是否仅包含 unicode 数字。小数点不是 unicode 数字并返回 false。
Null 将返回 false。空的String ("") 将返回true。
这在逻辑上正确吗? 为什么他们将空字符串视为数字?
【问题讨论】:
标签: java string apache-commons-lang
Apache 的 StringUtils.isNumeric() 方法规范说:
检查字符串是否仅包含 unicode 数字。小数点不是 unicode 数字并返回 false。
Null 将返回 false。空的String ("") 将返回true。
这在逻辑上正确吗? 为什么他们将空字符串视为数字?
【问题讨论】:
标签: java string apache-commons-lang
3.0 中的行为发生了变化。来自What's new in Commons Lang 3.0?:
StringUtils.isAlpha、isNumeric 和 isAlphanumeric 现在在传递空字符串时都返回 false。以前他们返回真。
保留下面的旧答案,以供参考和 3.0 之前的用户。
这在逻辑上正确吗?
我们有
在这种情况下 1 和 2 彼此一致;空字符串中的所有字符都是 unicode 数字。 (或者等效地,空字符串中的任何字符都不是 not unicode 数字。)这就是逻辑学家所说的 vacuously true 并且有点违反直觉。这就像说我公寓里所有的大象都是绿色的。这是真的,因为我的公寓里没有大象。
然而,第 3 项(方法的名称)自然地被解释为如果给定字符串表示数字则返回 true 的方法。
所以,要么是文档和实现错误,要么是命名错误。没有正确或错误的答案。
提交了一个错误here。维护者认为这是预期的行为。
为什么他们将空字符串视为数字?
虽然方法的名称可能会让您相信该方法应该只对表示数字的字符串返回 true,但规范实际上说它应该在字符串仅包含 unicode 数字时返回 true。
你说,
我很困惑,因为规范说:“检查字符串是否只包含 unicode 数字。”我没有看到 "" 包含数字....
请注意,空字符串不包含除 unicode 数字以外的任何内容。因此该方法返回 true。
【讨论】:
问这个问题的不只是我 :) 人们在 Apache 的 Jira 中打开了这个缺陷: https://issues.apache.org/jira/browse/LANG-428
他们没有修复就关闭了,只是为了保持向后兼容性(遵循方法规范)。
但是每个人都同意方法的当前行为是错误的。
【讨论】:
containsOnlyDigits 或 isNotNonNumeric。关于空字符串,有一些这样的惊喜。例如,您会说空字符串曾经包含任何内容吗?也就是说,"".contains(.....) 是否应该评估为真?嗯,确实如此! (我将把它作为练习留给你,让你弄清楚如何;)你只需要习惯这些,我们应该说空字符串的“反直觉属性”。
isActuallyNumeric() 或其他东西。
java.lang.Integer.parseInt("") 将失败。
这不是逻辑问题。这也不是常识问题——没有任何数字是由无符号表示的。为什么空字符串应该代表 0 没有强有力的论据。
如果方法名是containsOnlyNumeric(),根据我们的数学教科书,“”自然返回true。但是,方法名称是isNumeric(),“”的处理并不自然。此外,null 没有明显的理由返回 false。我会为 null 抛出异常。
但它就是这样,它有据可查,你还能要求什么?
【讨论】:
首先检查字符串是否为空()的条件。
if(StringUtils.isNotEmpty(str) && StringUtils.isNumeric(str)) {
}
那么你的问题就解决了。
但还有一个问题是您传递负值,例如
str = "-1";
StringUtils.isNumeric(str) 这将是错误的。
您需要注意这种情况。
【讨论】:
isNotEmpty?
还有另一种解决方案。 NumberUtils.isNumber 这会检查它是否是 Long、Double、Integer 中的数字。
希望有帮助
【讨论】:
从 Commons Lang 3.5 开始,NumberUtils.isCreatable 是执行此操作的方法。有关更详细的说明,请参阅this answer。
【讨论】: