Dla zupełności, przypadek „kilku zmiennych” jest rzeczywiście możliwy, chociaż wcale nie jest elegancki. Na przykład, dla zmiennych o, poraz q:
Optional.ofNullable( o ).orElseGet(()-> Optional.ofNullable( p ).orElseGet(()-> q ) )
Proszę zwrócić uwagę na zastosowanie obsługi orElseGet()sprawy, że o, pi qnie są zmiennymi, ale wyrażeniami albo drogimi, albo z niepożądanymi skutkami ubocznymi.
W najbardziej ogólnym przypadku 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
Może to generować zbyt długie wyrażenia. Jeśli jednak próbujemy przenieść się do świata bez null, v[i]to najprawdopodobniej już jesteśmy typu Optional<String>, a nie po prostu String. W tym przypadku,
result= o.orElse(p.orElse(q.get())) ;
lub w przypadku wyrażeń:
result= o.orElseGet(()-> p.orElseGet(()-> q.get() ) ) ;
Ponadto, jeśli są również przeprowadzki do stylu funkcjonalnym-deklaratywny, o, p, i qpowinny być typu Supplier<String>jak w:
Supplier<String> q= ()-> q-expr ;
Supplier<String> p= ()-> Optional.ofNullable(p-expr).orElseGet( q ) ;
Supplier<String> o= ()-> Optional.ofNullable(o-expr).orElseGet( p ) ;
A potem całość coalescesprowadza się po prostu do o.get().
Bardziej konkretny przykład:
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()i naturalnie ageFromInput()już wróci Optional<Integer>.
A potem coalescestaje się effectiveAge.get()lub po prostu, effectiveAgejeśli jesteśmy zadowoleni z Supplier<Integer>.
IMHO, w Javie 8 zobaczymy coraz więcej kodu o takiej strukturze, ponieważ jest on niezwykle samo-wyjaśniający i jednocześnie wydajny, szczególnie w bardziej złożonych przypadkach.
Tęsknię za klasą, Lazy<T>która wywołuje Supplier<T>tylko raz, ale leniwie, a także spójność w definicji Optional<T>(tj. Optional<T>- Optional<T>operatorów, a nawet Supplier<Optional<T>>).