Optional isPresent vs orElse(null)

2022-09-01 14:10:48

在我的项目中,我正在将依赖项更新到Spring 5,并且被编译错误轰炸,其中的方法定义已被替换为现在返回一个(如果我错了,请纠正我)。findOne()findById()Optional

在重构时,我遇到了多种我可以选择采用的方法,因此我希望对哪一种更可取提供一些意见。

第一种方法:

ExpectedPackage ep = expectedPackageRepository.findById(1).orElse(null);
if(ep != null){
    ep.setDateModified(new Date());
    expectedPackageRepository.saveAndFlush(ep);
}

第二种方法:

Optional<ExpectedPackage> ep = expectedPackageRepository.findById(1);
if(ep.isPresent()){
    ep.get().setDateModified(new Date());
    expectedPackageRepository.saveAndFlush(ep.get());
}

还是我错过了第三种更好的方法?我经历了几个问题和几篇文章,但我没有找到一个明确的答案。


答案 1

您还可以执行以下操作:

expectedPackageRepository.findById(1).ifPresent(
    ep -> {
        ep.setDateModified(new Date());
        expectedPackageRepository.saveAndFlush(ep);
    }
);

理想情况下,还可以将括号 () 之间的部分提取到单独的方法中。然后,你可以这样写:{}

    expectedPackageRepository.findById(1).ifPresent(this::doSomethingWithEp);

哪里:

void doSomethingWithEp(ExpectedPackage ep) {
    ep.setDateModified(new Date());
    expectedPackageRepository.saveAndFlush(ep);
}

您可以在此处阅读以下文档:https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html#ifPresent-java.util.function.Consumer-ifPresent

如它所述,如果值存在,它将执行指定的操作,否则不执行任何操作。


答案 2

是的,还有其他方法。

如果您绝对希望始终存在一个值,则使用 Optional::orElseThrow 在出现 null 时引发异常。

如果预计 null 可能会到达,并且有一个备用实例可用作回退选项,请使用 Optional::orElse

如果回退实例不在可用,但您有一个函数要调用来提供回退实例,请使用 Optional::orElseGet

如果您不关心接收 null,并且希望在 null 到达时不执行任何操作,请使用 Optional::ifPresent。传递要在值到达时运行的代码块。

如果您只关心值是否到达满足某些要求,请使用 Optional::filter。传递定义需求的谓词。例如,我们只关心包含文本并且该文本中包含单词:。如果收到 null,则我们所需的操作(在本例中调用)永远不会发生。如果收到一个值,但未能满足我们的谓词,则我们期望的操作永远不会发生。Optional< String >purplemyOptional.filter( s -> s.contains( "purple" ) ).ifPresent( this::print ) ;print


做是有效的,安全的。但这不是最初的意图,因为它基本上与进行老式的空检查相同。上的其他方法提供了一种更清晰、更优雅的方式来表达您对可能到达 null 的意图。if( myOptional.isPresent() ) { SomeClass x = myOptional.get() ; … }Optionalif ( null == x ) { … }Optional


推荐