如何使用Java Optional优雅地替换三元运算符

时间:2018-11-08 22:46:55

标签: java lambda java-8 optional

一个非常简单的问题:

这是我使用传统三元运算符?

的纯Java代码
public DateTime getCreatedAt() {
    return !recordA.isPresent() ? recordB.get().getCreatedAt() : recordA.get().getCreatedAt();
}

我最好的选择是:

public DateTime getCreatedAt() {
    return recordA.map(
        record -> record.getCreatedAt())
        .orElse(recordB.get().getCreatedAt());
  }

这可以编译,但是看起来行为不正确。 它总是执行两个分支,例如当recordA是isPresent()时,它仍然执行recordB.get().getCreatedAt()并抛出我

java.util.NoSuchElementException: No value present

任何人都感激不尽! 基本上,我想用更高级的Optional / lamda功能代替传统的三元选项。谢谢!

4 个答案:

答案 0 :(得分:8)

为避免急于评估其他分支,请使用orElseGet,它使用功能接口Supplier的一个实例:

return recordA.map(
    record -> record.getCreatedAt())
    .orElseGet(() -> recordB.get().getCreatedAt());

答案 1 :(得分:6)

我关于recordBOptional的问题没有得到解答,但是如果是Optional,则不能安全地调用其get方法,则需要检查它是否为空或不。这里安全调用以获取记录;如果recordArecordB均为空的Otional,则返回null。

        recordA
            .map(Record::getCreatedAt)
            .orElseGet( () -> recordB.map(Record::getCreatedAt).orElse(null) );

答案 2 :(得分:5)

您正在寻找.orElseGet(() -> recordB.get().getCreatedAt());,其原因可以在这篇文章中找到-> Difference between Optional.orElse() and Optional.orElseGet()

有些人可能会觉得它有些主观,但就我个人而言,默认情况下,每次使用orElseGet()而不是orElse更为合理,除非默认对象已经构造好了,因为这样可以避免很多意外的问题(假设您没有读过orElse和orElseGet文档之间的区别),就像现在要面对的那样。

进一步了解Java Optional – orElse() vs orElseGet()

答案 3 :(得分:0)

如果您使用的是 Java 9+,则可以使用 ifPresentOrElse() 方法 as more completely explained in this Stackoverflow answer

localhost