可选isPresent vs orElse(null)
我在我的项目中更新了Spring 8的依赖项,并被编译错误轰炸,其中findOne()
的方法定义已被findById()
替换,现在返回一个Optional
(如果我错了,请纠正我)。
在重构的过程中,我遇到了多种我可以选择采用的方法,因此我想要一些关于哪一种是首选的输入。
第一种方法:
ExpectedPackage ep = expectedPackageRepository.findById(1).orElse(null); if(ep != null){ ep.setDateModified(new Date()); expectedPackageRepository.saveAndFlush(ep); }
第二种方法:
Optional ep = expectedPackageRepository.findById(1); if(ep.isPresent()){ ep.get().setDateModified(new Date()); expectedPackageRepository.saveAndFlush(ep.get()); }
或者,我错过了第三种更好的方法吗? 我经历了几个问题和几篇文章,但我没有找到明确的答案。
你也可以这样做:
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); }
您可以在此处阅读ifPresent
的文档: https : ifPresent
如它所述,如果值存在,它将执行指定的操作,否则不执行任何操作。
另一个答案基本上是对你的第二种方法的一些重构,这本身没有任何错误,这只是一种风格问题。 当然,链接和提取到一个单独的方法将使这更加可读和清晰,毫无疑问(+1来自我),特别是因为正确使用ifPresent
。
我只是在这里添加get
,好吧,被视为某种设计错误(或者可能是一个糟糕的方法名称,可能来自guava
心态)。 使用get
即使它记录为在缺少该值时抛出exception也有点奇怪(如果你认为getter在这里,你不会指望getter
抛出exception)。 并且你不会期望在 isPresent
之后需要调用isPresent
,至少在与Optional
第一次交互时不需要调用。 因此get
建议被弃用(并且希望被删除),因此java-10添加了一个更好的加法orElseThrow()
– 这在您阅读之后就有意义,因为抛出部分是在方法的名称中,所以没有惊喜。
此外,有人应该告诉你使用new Date()
,当与java-8中的Optional
使用时看起来很奇怪,已经有更好的时间/日期相关类了。
我也不太确定为什么要手动更新修改日期,当有像PreUpdate/PrePersist
这样的弹簧注释时。
是的,还有其他方法。
如果你绝对希望总有一个值,那么如果出现null,则使用Optional::orElseThrow
抛出exception。
如果您希望null可能到达,并且有一个替代实例可用作后备选项,请使用Optional::orElse
。
如果没有后备实例,但您有一个函数可以调用以提供后备实例,请使用Optional::orElseGet
。
如果您不关心接收null,并且在null到达时想要什么都不做,请使用Optional::ifPresent
。 如果值到达,则传递要运行的代码块。
如果您只关心符合某些要求的值,请使用Optional::filter
。 传递定义您的要求的Predicate
。 例如,我们只关心一个Optional< String >
包含文本, 并且该文本中包含单词purple
: myOptional.filter( s -> s.contains( "purple" ) ).ifPresent( this::print ) ;
。 如果收到null,则不会发生我们所需的操作(在此示例中调用print
)。 如果收到一个值但未能满足我们的谓词,我们所希望的操作永远不会发生。
做if( myOptional.isPresent() ) { SomeClass x = myOptional.get() ; … }
if( myOptional.isPresent() ) { SomeClass x = myOptional.get() ; … }
是有效的,也是安全的。 但这不是Optional
的原始意图,因为它与执行旧式null检查if ( null == x ) { … }
。 关于Optional
的其他方法提供了一种更清晰,更优雅的方式来表达您对可能的空到达的意图。
你也可以这样做:
Optional updatedPackage = expectedPackageRepository.findById(1).map(ep -> { ep.setDateModified(new Date()); return expectedPackageRepository.saveAndFlush(ep); });