问题描述
我有一个字符串,我想将其解析为一个布尔值。如果它不包含true
或false
字符串,则应返回默认值(在我的情况下为true
)。
"true" -> true
"false" -> false
"something" -> true
我正在寻找Java方法或某些实用程序(Apache Commons或Guava)。
我无法使用Java方法Boolean.parseBoolean
,因为它没有带有默认值的参数(默认值始终为false
):
System.out.println(Boolean.parseBoolean("true")); // true
System.out.println(Boolean.parseBoolean("false")); // false
System.out.println(Boolean.parseBoolean("something")); // false instead of true
与Apache Commons BooleanUtils.toBoolean
相同:
System.out.println(BooleanUtils.toBoolean("true")); // true
System.out.println(BooleanUtils.toBoolean("false")); // false
System.out.println(BooleanUtils.toBoolean("something")); // false instead of true
我可以编写自己的方法:
private static Boolean toBoolean(String value,boolean defaultValue) {
return Optional.ofNullable(BooleanUtils.toBooleanObject(value))
.orElse(defaultValue);
}
并使用它:
System.out.println(toBoolean("true",true)); // true
System.out.println(toBoolean("false",true)); // false
System.out.println(toBoolean("something",true)); // true (that's what I want!)
但是,我希望某些util中存在将方法解析为具有默认值的布尔值的方法,或者我可以通过更简单的方式(在lambda链中使用一个衬里)来做到这一点。
解决方法
此方法在任何标准库中都不存在,也不应该存在,因此,您应该自己编写。 Apache中有类似的东西,但是默认情况下它为false,并且在apache公共库中也是如此,这是您不应该使用的不好的方法。核心库中也有类似的东西(Boolean.parseBoolean
),但是它也默认为false,这也是您不应该使用的不好的方法。在这里编写您自己的方法是正确的策略。
您的实现有点奇怪:
- 即使
null
本身已经可以很好地发挥作用,它也会绕着equals
跳舞 - 这是一个琐碎的实用程序方法,它使用整个库只是调用其中包含的琐碎的实用程序方法。这个不是JavaScript的语言-you dont want a left-pad debacle肯定是一件微不足道的事情。
- 即使实际上无法返回奇异的
null
,它也会使用大写B布尔值。
为什么不保持简单?
public boolean isFalse(String in) {
return "false".equals(in);
}
public boolean isTrue(String in) {
return "true".equals(in);
}
这些方法:
- 完全按照自己的意愿做
- 他们的名字准确地反映了它的作用,甚至可以使调用者很好地猜测如果您使用非
"true"
/"false"
输入来调用它们会发生什么。 - 非常简单
如果您必须使用defaultValue概念,那么我将坚持使代码尽可能地可读,即使付出一些时间:
public boolean toBoolean(String value,boolean defaultValue) {
if ("true".equals(value)) return true;
if ("false".equals(value)) return false;
return defaultValue;
}
好的,但是为什么该方法在实用程序库中不存在?
通常的原则是:“如果发生意外情况,只需在暗中暗中暗指其含义并继续下去”,这是PHP和javascript等语言中的一种常见操作模式。
幸运的是,java生态系统通常根本不遵守该原则-为此,我对Java生态系统和语言给予了很多荣誉,因为该原则在我看来似乎是完全落后的。
假设有一些方法。给定该方法的签名而没有其他信息,无论如何,您给我提供了该方法的大量输入,并要求我猜测该方法应该做什么。如果您要求的几乎所有程序员都正确地输入了每个样本输入答案,那么该方法就是好名字。
在某些情况下,这是不可能的(这样做太复杂了,您无法用简单的方法名称来描述它,因此需要进行文档读取)。关键不是所有方法都应该像这样,而仅仅是,如果一个方法可以那样,那么应该应该是。
剩下很多案例。希望每个人都可以猜到toBoolean("true")
返回的是true,但是如果我问toBoolean("oui")
会做什么,这将变得很棘手。当然,许多法国程序员会猜到true
,而一些非法国程序员也会猜到。我提出以下规则:您会从规则中得到一个“出局”,程序员应仅凭名称和签名就能够猜测方法的作用:如果程序员难以猜测的任何输入都会导致异常,那没关系。
例外情况是充当一个巨大的红色箭头-将调试转变为5秒钟的工作(相对于7天的野鹅追逐。考虑一下:如果他们都容易被抓住,我宁愿解决100个错误通过测试,每个测试需要花费一分钟的时间,而一个难以测试的错误会影响生产和客户,并且需要一周的时间才能解决!)。因此,解决这个问题:您是API设计人员,调用者是您的客户。如果您(toBoolean
方法的作者)不确定呼叫者打算做什么(例如,呼叫者向您提供了字符串"oui"
),不要猜测 。扔东西。或者,或者确保方法签名(名称+参数类型)不被干扰,以便清楚将要发生的事情。
不幸的是,apache的库往往会弄错这一点。但是请注意,java自己的Boolean.parseBoolean
也可以做到这一点(它不区分大小写,其中不区分大小写的"true"
为true,所有其他字符串为false),所以也许这是时代-两者都写得早于20年前,自那时以来社区的通用标准也在不断发展。