Java Optional.ifPresent()的正确用法
我试图理解Java 8中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
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是的,就是这样。您不应该期望从那里返回值;这更像是“做这个”。