我试图理解Java 8中ifPresent()
API的Optional
方法。
我有简单的逻辑:
Optional<User> user=...
user.ifPresent(doSomethingWithUser(user.get()));
但这会导致编译错误:
ifPresent(java.util.functionError:(186, 74) java: 'void' type not allowed here)
我当然可以这样做:
if(user.isPresent())
{
doSomethingWithUser(user.get());
}
但这就像一个杂乱的null
检查。
如果我将代码更改为:
user.ifPresent(new Consumer<User>() {
@Override public void accept(User user) {
doSomethingWithUser(user.get());
}
});
代码变得越来越脏,这让我想到回到旧的null
检查。
有任何想法吗?
Optional<User>.ifPresent()
以Consumer<? super User>
为参数。你传递的是一个类型为void的表达式。所以这不编译。
Consumer旨在实现为lambda表达式:
Optional<User> user = ...
user.ifPresent(theUser -> doSomethingWithUser(theUser));
甚至更简单,使用方法参考:
Optional<User> user = ...
user.ifPresent(this::doSomethingWithUser);
这与基本相同
Optional<User> user = ...
user.ifPresent(new Consumer<User>() {
@Override
public void accept(User theUser) {
doSomethingWithUser(theUser);
}
});
这个想法是只有在用户在场时才会执行doSomethingWithUser()
方法调用。您的代码直接执行方法调用,并尝试将其void结果传递给ifPresent()
。
除了@ JBNizet的答案之外,我对ifPresent
的一般用例是结合.isPresent()
和.get()
:
旧方式:
Optional opt = getIntOptional();
if(opt.isPresent()) {
Integer value = opt.get();
// do something with value
}
新方法:
Optional opt = getIntOptional();
opt.ifPresent(value -> {
// do something with value
})
对我来说,这更直观。
使用flatMap。如果存在值,则flatMap返回仅包含该值的顺序Stream,否则返回空Stream。所以没有必要使用ifPresent()
。例:
list.stream().map(data -> data.getSomeValue).map(this::getOptinalValue).flatMap(Optional::stream).collect(Collectors.toList());
你可以像这样使用方法参考:
user.ifPresent(ClassNameWhereMethodIs::doSomethingWithUser);
方法qazxsw poi将qazxsw poi对象作为参数和(来自ifPresent()
):“如果存在值,则使用值调用指定的使用者。”值它是你的变量Consumer
。
或者,如果这个方法JavaDoc在user
类中并且它不是doSomethingWithUser
,则可以使用如下方法引用:
User
为什么要简单地编写复杂的代码?
实际上,如果你绝对要使用static
类,那么最简单的代码就是你已经写过的......
user.ifPresent(this::doSomethingWithUser);
这段代码具有存在的优点
仅仅因为Oracle在Java 8中添加了Optional
类并不意味着必须在所有情况下使用此类。