I have a number of functions:
String first(){}
String second(){}
...
String default(){}
Each can return a null value, except the default. <
String s = Stream.>of(this::first, this::second /*, ... */)
.map(Supplier::get)
.filter(Objects::nonNull)
.findFirst()
.orElseGet(this::defaultOne);
It stops on the first non-null value or else sets the value which is returned from defaultOne
. As long as you stay sequential, you are safe. Of course this requires Java 8 or later.
The reason why it stops on the first occurrence of a non-null value is due how the Stream handles each step. The map is an intermediate operation, so is filter. The findFirst on the other side is a short-circuiting terminal operation. So it continues with the next element until one matches the filter. If no element matches an empty optional is returned and so the orElseGet-supplier is called.
this::first
, etc. are just method references. If they are static replace it with YourClassName::first
, etc.
Here is an example if the signature of your methods would differ:
String s = Stream.>of(() -> first("takesOneArgument"),
() -> second("takes", 3, "arguments")
/*, ... */)
.map(Supplier::get)
.filter(Objects::nonNull)
.findFirst()
.orElseGet(this::defaultOne);
Note that the Supplier is only evaluated when you call get
on it. That way you get your lazy evaluation behaviour. The method-parameters within your supplier-lambda-expression must be final or effectively final.