如果返回的Optional具有值,则按原样返回Optional,否则调用另一个函数

时间:2019-01-18 09:43:18

标签: java java-8 optional flatmap

我有两个方法func1和func2,它们返回Optional。 如果从func1返回的Optional具有值,则按原样返回Optional,否则调用func2并返回其Optional。 一种方法是使用if-else

Optional<MyObject> opt1 = func1();
if (opt1.isPresent()) {
    return opt1;
}
return func2();

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

类似的东西:

return Optional.of(obj1) 
        .flatMap_returnOptionalIfvaluePresent(func1)
        .orElseReturnOptionalFromThis(func2)

有人可以建议一个好方法吗?

5 个答案:

答案 0 :(得分:3)

编辑:or

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

Optional<String> myFunc() {
    return func1().or(this::func2);
}

or(在Java 9中引入)完全满足您的要求:如果从Optional返回的func1有一个值,则返回它(或等效的{{1} }。如果不是,则调用供应商(此处为Optional)以获取func2(),然后将其返回。

Java 8

有几种方法。在Java 8中,我更喜欢从OptionalOptional的{​​{1}} s中取值:

func1

编辑2: @Holger在评论中的替代建议足以在答案中引述(Holger,您可能仅将其作为评论发布,因为问题已经结束,因此您无法发表您自己的答案):

func2

这是相反的情况:使用Optional<String> myFunc() { String returnValue = func1().orElse(func2().orElse(null)); return Optional.ofNullable(returnValue); } 的映射将 return func1().map(Optional::of).orElse(func2()); 中的Optional::of包裹在Optional内,并且仅包含一个值,{{1 }}再次将其解包。

如果对func1的调用费用昂贵,则您可能希望在不需要它时(在Optional提供值时)避免使用它:

orElse

或者在Holger版本中:

func2
在其他几个答案中使用的

func1太低级了,我很少使用它,只是作为不得已而为之。

答案 1 :(得分:2)

如果您使用的是 java 9 + ,则可以只使用Optional.or

return func1().or(() -> func2());

Java 8 中,您可能需要根据结果创建一个新的Optional(使用orElseGet以避免急于执行):

return Optional.ofNullable(func1().orElseGet(() -> func2().orElse(null)));

答案 2 :(得分:0)

类似

Object value1 = func1();
return value1.isPresent() ? value1 : func2();

除非我误解了之后的内容,否则它将从第一个函数返回值(如果存在),并且如果不存在,则调用func2()返回第二个可选值。您可能可以将其进一步简化为func1().isPresent,但这使它变得不太清楚。

答案 3 :(得分:0)

如果我正确理解了所有内容,那将是一件好事:

Optional.of(obj1)
        .filter(obj -> func1().isPresent())
        .orElse(func2());

答案 4 :(得分:0)

这是使用n函数的更通用的版本:

private static <T> Optional<T> firstPresent(Supplier<Optional<T>>... optionals) {
    return Stream.of(optionals)
            .map(Supplier::get)
            .filter(Optional::isPresent)
            .findFirst()
            .orElse(Optional.empty());
}

要这样使用:

    Optional<String> result = firstPresent(() -> func1(null), () -> func2("abc"));