Hanya untuk kelengkapan, kasus "beberapa variabel" memang mungkin, meskipun tidak elegan sama sekali. Misalnya, untuk variabel o
, p
dan q
:
Optional.ofNullable( o ).orElseGet(()-> Optional.ofNullable( p ).orElseGet(()-> q ) )
Harap dicatat penggunaan orElseGet()
menghadiri untuk kasus yang o
, p
dan q
tidak variabel tapi ekspresi baik mahal atau dengan yang tidak diinginkan efek samping.
Dalam kasus yang paling umum 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
Ini bisa menghasilkan ekspresi terlalu lama. Namun, jika kita mencoba untuk pindah ke dunia tanpa null
, maka v[i]
kemungkinan besar sudah bertipe Optional<String>
, bukan hanya String
. Pada kasus ini,
result= o.orElse(p.orElse(q.get())) ;
atau dalam hal ekspresi:
result= o.orElseGet(()-> p.orElseGet(()-> q.get() ) ) ;
Selain itu, jika Anda juga pindah ke gaya fungsional-deklaratif, o
, p
, dan q
harus dari jenis Supplier<String>
seperti di:
Supplier<String> q= ()-> q-expr ;
Supplier<String> p= ()-> Optional.ofNullable(p-expr).orElseGet( q ) ;
Supplier<String> o= ()-> Optional.ofNullable(o-expr).orElseGet( p ) ;
Dan kemudian keseluruhan coalesce
dikurangi menjadi o.get()
.
Untuk contoh yang lebih konkret:
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()
dan ageFromInput()
sudah akan kembali Optional<Integer>
, secara alami.
Dan kemudian coalesce
menjadi effectiveAge.get()
atau hanya effectiveAge
jika kita senang dengan Supplier<Integer>
.
IMHO, dengan Java 8 kita akan melihat semakin banyak kode terstruktur seperti ini, karena sangat jelas dan efisien pada saat yang sama, terutama dalam kasus yang lebih kompleks.
Saya melewatkan kelas Lazy<T>
yang memanggil Supplier<T>
hanya satu kali, tetapi malas, serta konsistensi dalam definisi Optional<T>
(yaitu Optional<T>
- Optional<T>
operator, atau bahkan Supplier<Optional<T>>
).