Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I concisely write a || b where a and b are Optional values?

I'm happy with an answer in any language, but I ultimately want an answer in Java. (Java 8+ is fine. Not limited to Java 8. I've tried to fix the tags.)

If I have two Optional<Integer> values, how do I concisely compute the equivalent of a || b, meaning: a, if it's defined; otherwise b, if it's defined; otherwise empty()?

Optional<Integer> a = ...;
Optional<Integer> b = ...;
Optional<Integer> aOrB = a || b; // How to write this in Java 8+?

I know that I can write a.orElse(12), but what if the default "value" is also Optional?

Evidently, in C#, the operator ?? does what I want.

like image 388
J. B. Rainsberger Avatar asked Oct 24 '17 13:10

J. B. Rainsberger


3 Answers

In java-9 you can follow any of these :

✓ Simply chain it using the or as :-

Optional<Integer> a, b, c, d; // initialized
Optional<Integer> opOr = a.or(() -> b).or(() -> c).or(() -> d);

implementation documented as -

If a value is present, returns an Optional describing the value, otherwise returns an Optional produced by the supplying function.


✓ Alternatively as pointed out by @Holger, use the stream as:-

Optional<Integer> opOr = Stream.of(a, b, c, d).flatMap(Optional::stream).findFirst();

implementation documented as -

If a value is present, returns a sequential Stream containing only that value, otherwise returns an empty Stream.

like image 143
Naman Avatar answered Nov 14 '22 05:11

Naman


Optional<Integer> aOrB =  a.isPresent() ? a : b;
like image 8
Chirlo Avatar answered Nov 14 '22 03:11

Chirlo


In java-8 we don't have any solution to easy chain Optional objects, but you can try with:

Stream.of(a, b)
    .filter(op -> op.isPresent())
    .map(op -> op.get())
    .findFirst();

In java9 you can do:

Optional<Integer> result = a.or(() -> b);
like image 7
ByeBye Avatar answered Nov 14 '22 03:11

ByeBye