Solo por completitud, el caso de "varias variables" es de hecho posible, aunque no elegante en absoluto. Por ejemplo, para las variables o
, p
y q
:
Optional.ofNullable(o).orElseGet(()-> Optional.ofNullable(p).orElseGet(()-> q))
Tenga en cuenta el uso de orElseGet()
asistir al caso de que o
, p
y q
no son variables sino expresiones caros o con efectos secundarios no deseados.
En el caso más general 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
Esto puede generar expresiones excesivamente largo. Sin embargo, si estamos tratando de movernos a un mundo sin null
, entonces v[i]
probablemente ya sean del tipo Optional<String>
, en lugar de simplemente String
. En este caso,
result= o.orElse(p.orElse(q.get())) ;
o en el caso de las expresiones:
result= o.orElseGet(()-> p.orElseGet(()-> q.get())) ;
Por otra parte, si también se está moviendo a un estilo funcional-declarativa, o
, p
y q
debe ser de tipo Supplier<String>
como en:
Supplier<String> q=()-> q-expr ;
Supplier<String> p=()-> Optional.ofNullable(p-expr).orElseGet(q) ;
Supplier<String> o=()-> Optional.ofNullable(o-expr).orElseGet(p) ;
Y entonces todo el coalesce
reduce simplemente a o.get()
.
Para un ejemplo más concreto:
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()
y ageFromInput()
ya se volverían Optional<Integer>
, naturalmente.
Y entonces el coalesce
convierte effectiveAge.get()
o simplemente effectiveAge
si estamos contentos con un Supplier<Integer>
.
En mi humilde opinión, con Java 8 vamos a ver cada vez más código estructurado de esta manera, ya que es extremadamente autoexplicativo y eficiente al mismo tiempo, especialmente en casos más complejos.
no se pierda una clase Lazy<T>
que invoca un Supplier<T>
sólo una vez, pero con pereza, así como la coherencia en la definición de Optional<T>
(es decir Optional<T>
- Optional<T>
operadores, o incluso Supplier<Optional<T>>
).
Usted no debe necesitar una función como esta ya que genally no calcularía 'c' si 'b' tiene la respuesta que desea. es decir, no construirías una lista de posibles respuestas solo para mantener una. –
Advertencia: no todos los cortocircuitos RDBMS en COALESCE. Oracle solo recientemente comenzó a hacerlo. –
@ BrainSlugs83 ¿En serio? Java debería? –