正确使用Optional.ifPresent()

时间:2014-06-15 09:33:30

标签: java lambda java-8 optional

我正在尝试了解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支票。

有什么想法吗?

5 个答案:

答案 0 :(得分:103)

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()

答案 1 :(得分:11)

除了@ 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
})

对我来说,这更直观。

答案 2 :(得分:4)

使用flatMap。如果存在值,则flatMap返回仅包含该值的顺序Stream,否则返回空Stream。因此无需使用ifPresent()。例如:

list.stream().map(data -> data.getSomeValue).map(this::getOptinalValue).flatMap(Optional::stream).collect(Collectors.toList());

答案 3 :(得分:3)

您需要像这样使用它:

user.ifPresent(ClassNameWhereMethodIs::doSomethingWithUser);

方法ifPresent()获取Consumer对象作为参数和(来自JavaDoc):&#34;如果存在值,则使用值调用指定的使用者。&#34 ;将其变量user赋值。

答案 4 :(得分:2)

为什么要编写简单的复杂代码?

实际上,如果您绝对要使用Optional类,那么最简单的代码就是您已经编写的代码...

if (user.isPresent())
{
    doSomethingWithUser(user.get());
}

此代码的优点是

  1. 可读
  2. 易于调试(断点)
  3. 不棘手

仅仅因为Oracle在Java 8中添加了Optional类并不意味着在所有情况下都必须使用该类。