Nur der Vollständigkeit halber ist der Fall "mehrere Variablen" zwar möglich, aber überhaupt nicht elegant. Zum Beispiel für Variablen o, pund q:
Optional.ofNullable( o ).orElseGet(()-> Optional.ofNullable( p ).orElseGet(()-> q ) )
Bitte beachten Sie, dass Sie sich orElseGet()um den Fall kümmern omüssen p, dass qes sich nicht um Variablen handelt, sondern um Ausdrücke, die entweder teuer sind oder unerwünschte Nebenwirkungen haben.
Im allgemeinsten Fall coalesce(e[1],e[2],e[3],...,e[N])
coalesce-expression(i) == e[i] when i = N
coalesce-expression(i) == Optional.ofNullable( e[i] ).orElseGet(()-> coalesce-expression(i+1) ) when i < N
Dies kann zu lange Ausdrücke erzeugen. Wenn wir jedoch versuchen, uns in eine Welt ohne zu bewegen null, dann v[i]sind wir höchstwahrscheinlich schon vom Typ Optional<String>, im Gegensatz zu einfach String. In diesem Fall,
result= o.orElse(p.orElse(q.get())) ;
oder im Fall von Ausdrücken:
result= o.orElseGet(()-> p.orElseGet(()-> q.get() ) ) ;
Wenn Sie darüber hinaus auch zu einem funktionellen-deklarativem Stil bewegen, o, p, und qsollte vom Typ sein , Supplier<String>wie in:
Supplier<String> q= ()-> q-expr ;
Supplier<String> p= ()-> Optional.ofNullable(p-expr).orElseGet( q ) ;
Supplier<String> o= ()-> Optional.ofNullable(o-expr).orElseGet( p ) ;
Und dann coalescereduziert sich das Ganze einfach auf o.get().
Für ein konkreteres Beispiel:
Supplier<Integer> hardcodedDefaultAge= ()-> 99 ;
Supplier<Integer> defaultAge= ()-> defaultAgeFromDatabase().orElseGet( hardcodedDefaultAge ) ;
Supplier<Integer> ageInStore= ()-> ageFromDatabase(memberId).orElseGet( defaultAge ) ;
Supplier<Integer> effectiveAge= ()-> ageFromInput().orElseGet( ageInStore ) ;
defaultAgeFromDatabase(), ageFromDatabase()Und ageFromInput()würde schon zurückkehren Optional<Integer>, natürlich.
Und dann coalescewird das effectiveAge.get()oder einfach effectiveAgewenn wir mit einem zufrieden sind Supplier<Integer>.
IMHO, mit Java 8 werden wir immer mehr Code sehen, der so strukturiert ist, da er extrem selbsterklärend und gleichzeitig effizient ist, insbesondere in komplexeren Fällen.
Ich vermisse eine Klasse Lazy<T>, die Supplier<T>nur einmal, aber träge, sowie Konsistenz in der Definition von Optional<T>(dh Optional<T>- Optional<T>Operatoren oder sogar Supplier<Optional<T>>) aufruft .