I have the classic “Elvis operator” case, where I’m calling methods that each may return null and chaining them together:
thing?:nullableMethod1(a)?:nullableMethod2(b)?:nullableMethod3()
In Java 8, the most faithful implementation I’ve found is something like this:
return Optional.ofNullable(thing) .flatMap(x -> Optional.ofNullable(x.nullableMethod1(a))) .flatMap(y -> Optional.ofNullable(y.nullableMethod2(b))) .flatMap(z -> Optional.ofNullable(z.nullableMethod3()))
I wish that Java’s Optional
had something akin to the elvis operator:
public<U> Optional<U> elvisOperator(Function<? super T, ? extends U> mapper) { return flatMap(t -> Optional.ofNullable(mapper.apply(t)); }
So that I wouldn’t have to wrap each return value:
return Optional.ofNullable(thing) .elvisOperator(x -> x.nullableMethod1(a)) .elvisOperator(y -> y.nullableMethod2(b)) .elvisOperator(Z::nullableMethod3); // also nice
Is there a more efficient and idiomatic way to implement the Elvis operator pattern in Java 8?
Advertisement
Answer
Maybe I’m overlooking something, but is there a reason that you can’t use Optional#map
?
The following example prints nothing, as Optional
is short-circuiting in the sense that, if the value inside the Optional
doesn’t exist (it’s null
or the Optional
is empty), it’s treated as empty.
Optional.ofNullable("test") .map(s -> null) .ifPresent(System.out::println);
For that reason, I’d think you could just do the following:
return Optional.ofNullable(thing) .map(x -> x.nullableMethod1(a)) .map(y -> y.nullableMethod2(b)) .map(Z::nullableMethod3);
This would map your thing
if it exists, or return an empty Optional
otherwise.