0

Is there a concise pipeline-like pattern for Java's optional when having something like if - else if - else-like structures?

For example, we have two functions returning OptionalInts, and we want to use the result of f, if present, otherwise the result of g, if present, and otherwise 0:

OptionalInt f(...) {
    return ...
}

OptionalInt g(...) {
    return ...
}


int res = f(...).orElse(g(...).orElse(0));

Is there a more pipline-like structure of this pattern, e.g. (pseudocode)

int res = f(...)
    .orElseTry(g(...))
    .otherwise(0);
Alexander Ivanchenko
  • 25,667
  • 5
  • 22
  • 46
Green绿色
  • 1,620
  • 1
  • 16
  • 43
  • 2
    Does this answer your question? [Optional orElse Optional in Java](https://stackoverflow.com/questions/28818506/optional-orelse-optional-in-java) Probably not, though: the answers there work with `Optional`, not with `OptionalInt`. – Ole V.V. Jul 29 '22 at 05:06
  • 1
    As a complete aside, if the call to `g()` is costly, you may prefer `f().orElseGet(() -> g().orElse(0))`. It has nothing to do with solving the issue you asked about. – Ole V.V. Jul 29 '22 at 05:29
  • @OleV.V. Thank you. The link you provided is exactly what I was looking for. – Green绿色 Jul 29 '22 at 07:08

1 Answers1

1

With OptionalInt you can use orElseGet() (credits to @Ole V.V. since he has pointed it out in the comments earlier):

int res = f().orElseGet(() -> g().orElse(0));

In case if there are more than two sources for producing result, you can use the following approach:

int res = Stream.<Supplier<OptionalInt>>of(
        () -> f(),
        () -> g(),
        ...                           // other sources for producing the optional result    
    )                                 // Stream<Supplier<OptionalInt>>
    .map(Supplier::get)
    .filter(OptionalInt::isPresent)  // Stream<OptionalInt>>
    .mapToInt(OptionalInt::getAsInt) // IntStream
    .findFirst()                     // OptionalInt
    .orElse(0);
Alexander Ivanchenko
  • 25,667
  • 5
  • 22
  • 46
  • 1
    Thank you, the second code snipped looks good so far. I was indeed looking for a solution where I can try multiple sources in sequence and take the first producer's result that's not null. – Green绿色 Jul 29 '22 at 07:08