正确使用Optional.ifPresent()

问题描述 投票:60回答:5

我试图理解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检查。

有任何想法吗?

java lambda java-8 optional
5个回答
107
投票

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


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

对我来说,这更直观。


5
投票

使用flatMap。如果存在值,则flatMap返回仅包含该值的顺序Stream,否则返回空Stream。所以没有必要使用ifPresent()。例:

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

4
投票

你可以像这样使用方法参考:

user.ifPresent(ClassNameWhereMethodIs::doSomethingWithUser);

方法qazxsw poi将qazxsw poi对象作为参数和(来自ifPresent()):“如果存在值,则使用值调用指定的使用者。”值它是你的变量Consumer

或者,如果这个方法JavaDocuser类中并且它不是doSomethingWithUser,则可以使用如下方法引用:

User

2
投票

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

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

user.ifPresent(this::doSomethingWithUser);

这段代码具有存在的优点

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

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

© www.soinside.com 2019 - 2024. All rights reserved.