如何使用Java Optional API
以更优雅的方式重写以下代码:
first == null || second == null ? null : first + second;
如果两个变量中的任何一个变为null
或其他变量在其他地方,则代码应返回null
。
答案 0 :(得分:9)
我可以理解,也许你开始学习如何操作Optional
。这个怎么样?
String result =
Optional.ofNullable(first)
// v--- the trick is use the `flatMap` here.
.flatMap(left -> Optional.ofNullable(second).map(right-> left + right))
.orElse(null);
答案 1 :(得分:4)
如果你正在接受空值并返回空值,那么使用Optional
并不是非常有用。您可以将代码包装在Optional
中,但它看起来就像普通的空检查代码,并且有一些额外的垃圾。仅使用Optional
来检查空值仍然只是检查空值。如果您将整个方法重写为完全Optional
,则会得到如下内容:
public Optional<Integer> add(Optional<Integer> first, Optional<Integer> second)
{
return first.flatMap(left -> second.map(right -> left + right))
}
请注意,通过充分利用Optional接口,您不再需要担心null的特殊处理。此外,如果有人调用您的方法,则返回类型更加具体地说明在null / empty输入上发生的事情。
如果输入超出您的控制范围,正如您在评论中指出的那样,您可以使用Optional
将其打包在Optional.ofNullable
中,然后继续。如果你的输入和输出返回类型都是固定的,那么就像Optional
一样好,你就没有好用它。
答案 2 :(得分:3)
如果我们坚持你的要求:
如果两个变量中的任何一个为null或其总和在其他位置,则代码应返回null。
然后你根本不应该使用Optional
。它只会降低您的代码的可读性,并且难以维护。
Optional
的真正力量并不在于它的优雅,以避免无效检查(也不具备链式方法的诱惑潜力),而是表现为封装任何一种礼物的表现力或者缺席价值。使用它的最佳方式是作为方法的返回值。
在您的示例中,正如您所说,如果任一操作数为null
,该方法应返回null
,则您不会利用Optional
的潜力。另一方面,如果您有一个返回Optional
的方法(空或带总和),您将按预期使用它:
public Optional<Integer> firstPlusSecond() {
Optional<Integer> a = Optional.ofNullable(first);
Optional<Integer> b = Optional.ofNullable(second);
if (!a.isPresent() || !b.isPresent()) {
return Optional.empty();
}
return Optional.of(a.get() + b.get());
}
这实际上清楚地表达了您的意图,即返回的Optional
为空(如果一个操作数为null
)或保留first + second
的结果。
如果first
和second
都有可选的getter ,那就更好了:
public Optional<Integer> first() {
return Optional.ofNullable(first);
}
public Optional<Integer> second() {
return Optional.ofNullable(second);
}
这样,上面的firstPlusSecond()
方法现在转为:
public Optional<Integer> firstPlusSecond() {
Optional<Integer> a = first();
Optional<Integer> b = second();
if (!a.isPresent() || !b.isPresent()) {
return Optional.empty();
}
return Optional.of(a.get() + b.get());
}
其中,IMO,是更好的代码。
甚至更好,正如@ holi-java在评论中所建议的那样:
public Optional<Integer> firstPlusSecond() {
Optional<Integer> a = first();
Optional<Integer> b = second();
return a.isPresent() && b.isPresent() ?
Optional.of(a.get() + b.get()) :
Optional.empty();
}
或者,正如@ holi-java建议的那样,如果您不想为first
和second
创建可选的getter,但仍希望返回Optional
,你可以这样做:
public Optional<Integer> firstPlusSecond() {
return first != null && second != null ?
Optional.of(first + second) :
Optional.empty();
}
答案 3 :(得分:1)
这是我使用java流的解决方案
private Integer sum(Integer ...additions) {
return Arrays.stream(additions).filter(Objects::nonNull).reduce(0, Integer::sum);
}