6

I have several methods, that each are returning an optional string. How do I combine then, so that java calls each method, until it finds a result?

I'd like to end up with something like this, but there is not orElseFlatMap() method:

import java.util.Optional;

public class OptionalCascade {

    public static void main(String[] args) {
        Optional<String> result = 

                // try to get a result with method A
                methodA()

                // if method A did not return anything, then try method B
                .orElseFlatMap(methodB());
    }


    static Optional<String> methodA() {
        return Optional.empty();
    }

    static Optional<String> methodB() {
        return Optional.empty();
    }
}
slartidan
  • 20,403
  • 15
  • 83
  • 131
  • Do you want to short-circuit as soon as you get a result? In that case you can't just put method invocation in the construct. You'll have to wrap calls in lambdas (such as with `orElseGet(() -> methodB()` – Marko Topolnik Sep 18 '15 at 11:05
  • I'll just stay with good old if-else and nulls :) – ZhongYu Sep 18 '15 at 16:18

2 Answers2

4

Assuming you want to use standard methods and have single-expression solution, I can come up only with this:

Optional<String> result = Optional.ofNullable(methodA().orElseGet(
        () -> methodB().orElse(null)));

Ugly. Alternatively you may write your own static method:

public static <T> Optional<T> orElseFlatMap(Optional<T> optional,
        Supplier<Optional<T>> other) {
    return optional.isPresent() ? optional : other.get();
}

Optional<String> result = orElseFlatMap(methodA(), () -> methodB());
Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
  • Good suggestions for workarounds - but still not the "solution" I'm looking for... :( Thanks for your answer, anyways. – slartidan Sep 18 '15 at 11:07
  • 1
    @slartidan, probably you don't need to store the result as an optional. Just use `String result = methodA().orElseGet(() -> methodB().orElse(whatEver));` – Tagir Valeev Sep 18 '15 at 11:11
  • I assume OP wants to cascade more than two methods this way. This approach results in a nesting instead of cascading syntax. – Marko Topolnik Sep 18 '15 at 11:12
0

You can do something like a Chain-of-responsibility pattern where basically you just call your first method. Then inside your first method if you can return the result then return it. If it's empty then call your successor method.

Amr
  • 792
  • 3
  • 15
  • Thanks for your answer. I'm however looking for a Java8 solution in functional syntax for combining my optionals. I want to avoid if/else, etc. – slartidan Sep 18 '15 at 10:56