如果返回的Optional具有值,则返回可选,否则调用另一个函数

adi*_*moh 5 java optional java-8 flatmap

我有两个方法func1和func2返回Optional.如果从func1返回的Optional具有值,则返回可选,否则调用func2并返回其Optional.一种方法是使用if-else.

Optional<MyObject> opt1 = func1();
if (opt1.isPresent()) {
    return opt1;
}
return func2();
Run Code Online (Sandbox Code Playgroud)

但是,我希望使用Java 8 Optional来实现它并避免使用它if-else.

就像是:

return Optional.of(obj1) 
        .flatMap_returnOptionalIfvaluePresent(func1)
        .orElseReturnOptionalFromThis(func2)
Run Code Online (Sandbox Code Playgroud)

任何人都可以建议一个好方法吗?

Ole*_*.V. 6

编辑: or

Java 9 及更高版本提供了一个非常优雅的解决方案:

Optional<String> myFunc() {
    return func1().or(this::func2);
}
Run Code Online (Sandbox Code Playgroud)

or(在 Java 9 中引入)完全符合您的要求:如果Optional返回的 fromfunc1具有值,则返回(或等效的Optional)。如果不是,func2()则调用供应商(此处为)以获取Optional,然后返回该 。

爪哇 8

有几种方法。在 Java 8 中,我更喜欢Optional从 sfunc1和 中取出值func2

Optional<String> myFunc() {
    String returnValue = func1().orElse(func2().orElse(null));
    return Optional.ofNullable(returnValue);
}
Run Code Online (Sandbox Code Playgroud)

编辑 2: @Holger 在评论中的替代建议足以在答案中引用(Holger,您可能将其作为评论发布只是因为问题已关闭,因此您无法发布自己的答案):

    return func1().map(Optional::of).orElse(func2());
Run Code Online (Sandbox Code Playgroud)

它以相反的方式进行:映射 using仅当它具有值时才从内部Optional::of包装,然后再次将其解开。Optionalfunc1OptionalorElse

如果调用func2成本很高,您可能希望在不需要它时避免它(当func1提供一个值时):

    String returnValue = func1().orElseGet(() -> func2().orElse(null));
Run Code Online (Sandbox Code Playgroud)

或者在 Holger 的版本中:

    return func1().map(Optional::of).orElseGet(this::func2);
Run Code Online (Sandbox Code Playgroud)

isPresent 在其他几个答案中使用的级别非常低,我很少使用它,并且仅作为最后的手段。

  • 使用 `func1().orElseGet(() -&gt; func2().orElse(null))` 会带来轻微的改进,因为 `func2` 不会急切地执行。好的解决方案。 (2认同)
  • 是的,@ernest_k,这正是我在答案底部附近所说的。英雄所见略同。:-) (2认同)