如何使用 Java Optional 优雅替换三元运算符
How to use Java Optional to elegantly replace Ternary operators
一个超级简单的问题:
这是我使用传统三元运算符 ?
的纯 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 功能替换传统的三元运算符。
为了避免急切地评估 else 分支,使用 orElseGet
,它采用功能接口 Supplier
:
的实例
return recordA.map(
record -> record.getCreatedAt())
.orElseGet(() -> recordB.get().getCreatedAt());
您正在寻找 .orElseGet(() -> recordB.get().getCreatedAt());
,原因可以在 post -->
中找到
有些人可能会觉得它有点主观,但就我个人而言,默认情况下,每次都使用 orElseGet()
而不是 orElse
更有意义,除非默认对象已经构建,因为这将防止许多意外问题(假设您没有阅读 orElse 和 orElseGet 文档之间的差异),就像您现在面临的问题一样。
的更多内容
我关于 recordB
是 Optional
的问题没有得到回答,但如果它是 Optional
那么你不能安全地调用它的 get
方法,你需要检查它是否是否为空。如果 recordA
和 recordB
都为空 Otional
s.
,这里安全调用获取记录或 null
recordA
.map(Record::getCreatedAt)
.orElseGet( () -> recordB.map(Record::getCreatedAt).orElse(null) );
如果您使用的是 Java 9+,您可以使用 ifPresentOrElse() 方法 as more completely explained in this Whosebug answer.
recordA.ifPresentOrElse(
value -> recordA.get().getCreatedAt(),
() -> recordB.get().getCreatedAt()
);
一个超级简单的问题:
这是我使用传统三元运算符 ?
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 功能替换传统的三元运算符。
为了避免急切地评估 else 分支,使用 orElseGet
,它采用功能接口 Supplier
:
return recordA.map(
record -> record.getCreatedAt())
.orElseGet(() -> recordB.get().getCreatedAt());
您正在寻找 .orElseGet(() -> recordB.get().getCreatedAt());
,原因可以在 post -->
有些人可能会觉得它有点主观,但就我个人而言,默认情况下,每次都使用 orElseGet()
而不是 orElse
更有意义,除非默认对象已经构建,因为这将防止许多意外问题(假设您没有阅读 orElse 和 orElseGet 文档之间的差异),就像您现在面临的问题一样。
我关于 recordB
是 Optional
的问题没有得到回答,但如果它是 Optional
那么你不能安全地调用它的 get
方法,你需要检查它是否是否为空。如果 recordA
和 recordB
都为空 Otional
s.
recordA
.map(Record::getCreatedAt)
.orElseGet( () -> recordB.map(Record::getCreatedAt).orElse(null) );
如果您使用的是 Java 9+,您可以使用 ifPresentOrElse() 方法 as more completely explained in this Whosebug answer.
recordA.ifPresentOrElse(
value -> recordA.get().getCreatedAt(),
() -> recordB.get().getCreatedAt()
);