Java Optional.ifPresent() 的正确使用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24228279/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 10:56:46  来源:igfitidea点击:

Proper usage of Optional.ifPresent()

javalambdajava-8optional

提问by rayman

I am trying to understand the ifPresent()method of the OptionalAPI in Java 8.

我试图了解Java 8 中 API的ifPresent()方法Optional

I have simple logic:

我有简单的逻辑:

Optional<User> user=...
user.ifPresent(doSomethingWithUser(user.get()));

But this results in a compilation error:

但这会导致编译错误:

ifPresent(java.util.functionError:(186, 74) java: 'void' type not allowed here)

Of course I can do something like this:

当然,我可以这样做:

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

But this is exactly like a cluttered nullcheck.

但这就像一张杂乱的null支票。

If I change the code into this:

如果我把代码改成这样:

 user.ifPresent(new Consumer<User>() {
            @Override public void accept(User user) {
                doSomethingWithUser(user.get());
            }
        });

The code is getting dirtier, which makes me think of going back to the old nullcheck.

代码越来越脏,这让我想到回到旧null支票。

Any ideas?

有任何想法吗?

采纳答案by JB Nizet

Optional<User>.ifPresent()takes a Consumer<? super User>as argument. You're passing it an expression whose type is void. So that doesn't compile.

Optional<User>.ifPresent()将 aConsumer<? super User>作为参数。你传递给它一个类型为 void 的表达式。所以这不编译。

A Consumer is intended to be implemented as a lambda expression:

消费者旨在实现为 lambda 表达式:

Optional<User> user = ...
user.ifPresent(theUser -> doSomethingWithUser(theUser));

Or even simpler, using a method reference:

或者更简单,使用方法引用:

Optional<User> user = ...
user.ifPresent(this::doSomethingWithUser);

This is basically the same thing as

这与

Optional<User> user = ...
user.ifPresent(new Consumer<User>() {
    @Override
    public void accept(User theUser) {
        doSomethingWithUser(theUser);
    }
});

The idea is that the doSomethingWithUser()method call will only be executed if the user is present. Your code executes the method call directly, and tries to pass its void result to ifPresent().

这个想法是doSomethingWithUser()只有在用户存在时才会执行方法调用。您的代码直接执行方法调用,并尝试将其 void 结果传递给ifPresent()

回答by Aleksandr Podkutin

You can use method reference like this:

您可以像这样使用方法引用:

user.ifPresent(ClassNameWhereMethodIs::doSomethingWithUser);

Method ifPresent()get Consumerobject as a paremeter and (from JavaDoc): "If a value is present, invoke the specified consumer with the value." Value it is your variable user.

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

Or if this method doSomethingWithUseris in the Userclass and it is not static, you can use method reference like this:

或者,如果此方法doSomethingWithUserUser类中而它不在类中,则static可以使用如下方法引用:

user.ifPresent(this::doSomethingWithUser);

回答by cst1992

In addition to @JBNizet's answer, my general use case for ifPresentis to combine .isPresent()and .get():

除了@JBNizet 的回答,我的一般用例ifPresent是结合.isPresent().get()

Old way:

旧方式:

Optional opt = getIntOptional();
if(opt.isPresent()) {
    Integer value = opt.get();
    // do something with value
}

New way:

新方法:

Optional opt = getIntOptional();
opt.ifPresent(value -> {
    // do something with value
})

This, to me, is more intuitive.

对我来说,这更直观。

回答by Taras Melnyk

Use flatMap. If a value is present, flatMap returns a sequential Stream containing only that value, otherwise returns an empty Stream. So there is no need to use ifPresent(). Example:

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

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

回答by schlebe

Why write complicated code when you could make it simple?

既然可以简化代码,为什么还要编写复杂的代码?

Indeed, if you are absolutely going to use the Optionalclass, the most simple code is what you have already written ...

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

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

This code has the advantages of being

这段代码的优点是

  1. readable
  2. easy to debug (breakpoint)
  3. not tricky
  1. 可读的
  2. 易于调试(断点)
  3. 不棘手

Just because Oracle has added the Optionalclass in Java 8 doesn't mean that this class must be used in all situation.

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