-->

How do I concisely write a || b where a and b are

2019-03-25 17:28发布

问题:

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.

回答1:

Optional<Integer> aOrB =  a.isPresent() ? a : b;


回答2:

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.



回答3:

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);


回答4:

In java-8 if you want something close to the Optional::stream mechanic, you could do

Stream.of(a, b)
  .flatMap(x -> 
     x.map(Stream::of)
      .orElse(Stream.empty())
  )
  .findFirst()


回答5:

Hi you can do something like this.

a.orElse(b.orElse(null));