Java Optional.ifPresent()的正确用法

Java Optional.ifPresent()的正确用法,java,lambda,java-8,optional,Java,Lambda,Java 8,Optional,我试图理解Java 8中OptionalAPI的ifPresent()方法 我有一个简单的逻辑: Optional<User> user=... user.ifPresent(doSomethingWithUser(user.get())); 当然,我可以这样做: if(user.isPresent()) { doSomethingWithUser(user.get()); } user.ifPresent(ClassNameWhereMethodIs::doSomethin

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

我有一个简单的逻辑:

Optional<User> user=...
user.ifPresent(doSomethingWithUser(user.get()));
当然,我可以这样做:

if(user.isPresent())
{
  doSomethingWithUser(user.get());
}
user.ifPresent(ClassNameWhereMethodIs::doSomethingWithUser);
user.ifPresent(this::doSomethingWithUser);
但这与杂乱无章的
null
检查完全一样

如果我将代码更改为:

 user.ifPresent(new Consumer<User>() {
            @Override public void accept(User user) {
                doSomethingWithUser(user.get());
            }
        });
user.ifPresent(新消费者(){
@覆盖公共作废接受(用户){
doSomethingWithUser(user.get());
}
});
代码变得越来越脏,这让我想到回到旧的
null
检查


有什么想法吗?

可选。ifPresent()
接受
消费者您可以使用如下方法引用:

if(user.isPresent())
{
  doSomethingWithUser(user.get());
}
user.ifPresent(ClassNameWhereMethodIs::doSomethingWithUser);
user.ifPresent(this::doSomethingWithUser);
方法
ifPresent()

或者,如果此方法
doSomethingWithUser
User
类中并且不是
static
,则可以使用如下方法引用:

if(user.isPresent())
{
  doSomethingWithUser(user.get());
}
user.ifPresent(ClassNameWhereMethodIs::doSomethingWithUser);
user.ifPresent(this::doSomethingWithUser);

除了@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将返回仅包含该值的序列流,否则将返回空流。因此,无需使用
ifPresent()
。例如:

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

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

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

if (user.isPresent())
{
    doSomethingWithUser(user.get());
}
此代码的优点是

  • 可读的
  • 易于调试(断点)
  • 不狡猾

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

    但是doSomethingWithUser不是静态方法,也不是类。@rayman好的,如果不是静态的,您可以这样做:
    user.ifPresent(新的ClassNameWhereMethodIs():doSomethingWithUser)
    @AleksandrPodkutin您不应该仅仅为了运行一个方法而创建一个新的类实例,从OP上看,该方法听起来像是在从同一个类中调用它,因此他应该使用
    user.ifPresent(this::doSomethingWithUser)@Marv我没有看到任何关于它在同一个班级的确认表。但是如果你有这样的感觉,我同意他必须使用
    user.ifPresent(this::doSomethingWithUser)。我将把它添加到我的答案中。代码变得越来越混乱。。空检查将更干净。你不觉得吗?特别是doSomethingWithUser不是一个静态方法哪个代码?您应该使用的是第二个,它调用实例(即非静态)方法doSomethingWithUser()。我看不出有多凌乱。最后一段代码是用来解释在前lambda世界中lambda的等价物。不要使用它。是的,但是你可能已经习惯了匿名类,因此你可以通过看到一个匿名类来理解lambda的功能。这就是重点,你没有什么可以修改的。保持原样,使用第二个示例:
    user.ifPresent(this::doSomethingWithUser)
    @rayman如果您有一个返回
    Optional
    的函数,通常不需要将其存储在局部变量中。只需链接方法调用:
    funcThatMightReturnUser().ifPresent(this::doSomethingWithUser)可选::stream需要Java9使用ifPresent的主要好处是它不再需要手动调用get()。手动调用get()容易出错,因为很容易忘记先检查isPresent,但如果使用ifPresentOk,并且每次使用“user”对象时都应该调用.ifPresent(),则不可能忘记。代码将很快变得不可读,因为您将阅读.ifPresent()太多时间!但无论什么在里面,如果存在,就应该返回无效,因为你从里面返回的任何东西都是无效的lost@valik是的,就是这样。您不应该期望从那里返回值;这更像是“做这个”。