Return 如果返回的 Optional 有值,则为 Optional,否则调用另一个函数

Return Optional as it is if the returned Optional has value, else call another function

我有两个方法 func1 和 func2,return 可选。 Return 如果来自 func1 的 returned Optional 有值,则它是可选的,否则调用 func2 和 return 它的 Optional。 一种方法是使用 if-else.

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

但是,我希望使用 Java 8 可选并避免使用 if-else.

来实现它

类似于:

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

谁能推荐个好方法?

这样的东西呢
Object value1 = func1();
return value1.isPresent() ? value1 : func2();

除非我误解了你的意思,否则将 return 来自第一个函数的值(如果它存在),如果它不存在则调用 func2() 到 return 第二个可选。您可能可以将其进一步简化为 func1().isPresent,但它变得不太清晰。

如果我理解正确的话,它会是这样的:

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

编辑:or

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

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

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

Java 8

有几种方法。在 Java 8 中,我更喜欢从 func1func2:

中取出 Optional 的值
Optional<String> myFunc() {
    String returnValue = func1().orElse(func2().orElse(null));
    return Optional.ofNullable(returnValue);
}

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

    return func1().map(Optional::of).orElse(func2());

情况正好相反:使用 Optional::of 的映射将 func1 中的 Optional 包裹在 Optional 内部,但仅当它有一个值时 Optional,从中 orElse 再次打开它。

如果对 func2 的调用开销很大,您可能希望在不需要时避免它(当 func1 提供一个值时):

    String returnValue = func1().orElseGet(() -> func2().orElse(null));

或者在 Holger 的版本中:

    return func1().map(Optional::of).orElseGet(this::func2);

isPresent 在其他几个答案中使用的太低级了,我很少使用它,只是作为最后的手段。

这是一个更通用的版本,使用 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"));

如果您使用 java 9+,您可以只使用 Optional.or:

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

Java8中,您可能需要从结果中创建一个新的Optional(使用orElseGet以避免急切执行):

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