我想检查特定对象大小是否大于 0。如果它大于 0,那么我想创建一个可选对象,如果不是,那么我想返回一个空可选对象。这是 Java 代码的长版本:
if(fooA.size>0) {
return Optional.of(new Foo());
} else {
return Optional.empty();
}
有没有办法使用 Java 8 中引入的
Optional
API 将其压缩为一行?
有没有办法使用 java 8 的可选库将其压缩为一行?
Optional.ofNullable()
,如果不满足条件则直接通过null
:
return Optional.ofNullable(fooA.size > 0 ? new Foo() : null);
但是请注意(正如Holger正确指出的那样),与仅用三元语句替换 if/else 语句相比,使用Optional类并不会给你带来任何显着的1优势(正如tobias_k和Holger所言)两者都在他们的评论)中完成:
return fooA.size > 0 ? Optional.of(new Foo()) : Optional.empty();
1 第一行有点短,我通常认为这是一个优点,但在这种情况下绝对是微不足道,因为长度差异可以忽略不计。
如果您决定坚持命令式编程,那么您的 if-else 结构就很好。它具有可读性、可理解性,并且通过简单地减少代码行数你不会获得任何好处(除非你为此获得报酬并且想要玩弄系统)。
(condition)?(true-branch):(false-branch)
结构很好,但如果它变得太复杂,可读性可能会很差。一些自动格式规则无论如何都会将其每个部分放入单独的行中。所以使用前请三思。
将创建放入一行的最简单方法是将实例化重构为单独的方法并调用它:
return newOptionalFoo(fooA.size > 0);
...
private Optional<Foo> newOptionalFoo(boolean condition) {
if(condition) {
return Optional.of(new Foo());
} else {
return Optional.empty();
}
}
如果你想将其压缩为单行 - 命令式 - 执行以下操作:
return condition ? Optional.of(new Foo()) : Optional.empty();
如果您想使用函数式编程,则在可以避免的情况下不应混合使用函数式编程和命令式编程。 正确的功能方法是将
fooA
包装到可选中,根据条件进行过滤并映射到 Foo
。因此,如果不满足条件,则会将其映射到空的Optional
。我更喜欢这种方式。
return Optional.of(fooA).filter(f -> f.size > 0).map(f -> new Foo());
或者,您可以创建
Optional
的 Foo
并使用过滤器,以便如果过滤条件不匹配,可选内容将变为空:
return Optional.of(new Foo()).filter(f -> fooA.size > 0);
但是无论条件是真还是假,这都会创建
Foo
的实例。如果您想进行惰性实例化,因为创建 Foo
的成本很高,您可以使用 Supplier
并在过滤后映射到 Foo
return Optional.of((Supplier<Foo>) Foo::new)
.filter(s -> fooA.size > 0)
.map(Supplier::get)