Java 8可选

Ric*_*ard 1 java optional java-8

我想检查一个特定的对象大小是否大于0.如果它大于0然后我想创建一个可选对象,如果没有,那么我想返回一个Optional空.这是java代码的长版本:

if(fooA.size>0) {
    return Optional.of(new Foo());
} else {
    return Optional.empty();
}
Run Code Online (Sandbox Code Playgroud)

有没有办法使用java 8的可选库将其压缩成一行?

Sig*_*uza 7

有没有办法使用java 8的可选库将其压缩成一行?

如果您坚持使用Optional类,则可以使用Optional.ofNullable()并在null不满足条件时传递它:

return Optional.ofNullable(fooA.size > 0 ? new Foo() : null);
Run Code Online (Sandbox Code Playgroud)

但是请注意,(如霍尔格 正确地指出),使用可选的类不给你任何显著1个比只是一个三元替换您的if/else语句(如优势tobias_k和Holger已经在做了两个他们的 意见):

return fooA.size > 0 ? Optional.of(new Foo()) : Optional.empty();
Run Code Online (Sandbox Code Playgroud)

1第一行稍短,我通常认为这是一个优点,但在这种情况下绝对无关紧要,因为长度差异可以忽略不计.


Ger*_*cke 6

势在必行

如果您决定坚持使用命令式编程,那么按原样使用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();
  }
}
Run Code Online (Sandbox Code Playgroud)

如果您想将其压缩为单行(命令式),请执行以下操作:

return condition ? Optional.of(new Foo()) : Optional.empty();    
Run Code Online (Sandbox Code Playgroud)

功能方式

如果要使用函数式编程,则应避免将函数式和命令式编程混合使用。一种适当的功能性方法是将其包装fooA到Optional中,对条件进行过滤并映射到Foo。因此,如果不满足条件,则将其映射为empty Optional。我更喜欢这种方式。

return Optional.of(fooA).filter(f -> f.size > 0).map(f -> new Foo());
Run Code Online (Sandbox Code Playgroud)

或者,您可以创建Optionalof Foo并使用过滤器,以便在过滤条件不匹配时,可选参数变为空:

return Optional.of(new Foo()).filter(f -> fooA.size > 0);
Run Code Online (Sandbox Code Playgroud)

但这将创建一个实例,Foo无论条件为真还是假。如果由于创建a Foo花费昂贵而希望进行延迟实例化,则可以在过滤后使用Supplier和映射到Foo

return Optional.of((Supplier<Foo>) Foo::new)
               .filter(s -> fooA.size > 0)
               .map(Supplier::get)
Run Code Online (Sandbox Code Playgroud)