Di Java 8, saya ingin melakukan sesuatu ke Optional
objek jika ada, dan melakukan hal lain jika tidak ada.
if (opt.isPresent()) {
System.out.println("found");
} else {
System.out.println("Not found");
}
Ini bukan 'gaya fungsional'.
Optional
memiliki ifPresent()
metode, tetapi saya tidak dapat mengaitkan orElse()
metode.
Jadi, saya tidak bisa menulis:
opt.ifPresent( x -> System.out.println("found " + x))
.orElse( System.out.println("NOT FOUND"));
Sebagai balasan untuk @assylias, saya pikir ini tidak Optional.map()
berfungsi untuk kasus berikut:
opt.map( o -> {
System.out.println("while opt is present...");
o.setProperty(xxx);
dao.update(o);
return null;
}).orElseGet( () -> {
System.out.println("create new obj");
dao.save(new obj);
return null;
});
Dalam hal ini, ketika opt
ada, saya memperbarui propertinya dan menyimpan ke database. Ketika tidak tersedia, saya membuat yang baru obj
dan menyimpan ke database.
Catatan dalam dua lambda saya harus kembali null
.
Tetapi ketika opt
ada, kedua lambda akan dieksekusi. obj
akan diperbarui, dan objek baru akan disimpan ke database. Ini karena return null
dalam lambda pertama. Dan orElseGet()
akan terus dieksekusi.
sumber
return null;
denganreturn o;
(keduanya). Namun, saya memiliki perasaan kuat bahwa Anda bekerja di tempat yang salah. Anda harus bekerja di situs yang menghasilkan ituOptional
. Di tempat itu harus ada cara melakukan operasi yang diinginkan tanpa perantaraOptional
.ifPresent
bertentangan ini. Semua metode lain merujuk pada nilai dan bukan tindakan.Jawaban:
Bagi saya jawaban dari @Dane White adalah OK, pertama saya tidak suka menggunakan Runnable tapi saya tidak bisa menemukan alternatif, di sini implementasi lain saya lebih suka
Kemudian :
Pembaruan 1:
solusi di atas untuk cara pengembangan tradisional ketika Anda memiliki nilai dan ingin memprosesnya, tetapi bagaimana jika saya ingin mendefinisikan fungsionalitas dan pelaksanaannya nanti, periksa peningkatan di bawah ini;
Kemudian bisa digunakan sebagai:
Dalam kode baru ini Anda memiliki 3 hal:
ngomong-ngomong sekarang namanya lebih deskriptif itu sebenarnya Consumer>
sumber
Jika Anda menggunakan Java 9+, Anda dapat menggunakan
ifPresentOrElse()
metode:sumber
Java 9 memperkenalkan
ifPresentOrElse jika ada nilai, lakukan tindakan yang diberikan dengan nilai tersebut, jika tidak lakukan tindakan berbasis kosong yang diberikan.
Lihat Opsional yang sangat baik di lembar contekan Java 8 .
Ini memberikan semua jawaban untuk sebagian besar kasus penggunaan.
Ringkasan singkat di bawah ini
ifPresent () - lakukan sesuatu ketika Opsional diatur
filter () - tolak (filter out) nilai Opsional tertentu.
map () - mentransformasikan nilai jika ada
orElse () / orElseGet () - mengubah kosong Opsional ke standar T
orElseThrow () - malas melempar pengecualian pada Opsional kosong
sumber
map
, tetapi agak aneh untuk meminta solusi fungsional sehingga Anda dapat memanggil DAO. Menurut saya akan lebih masuk akal untuk mengembalikan objek yang diperbarui / baru darimap.orElse
blok ini dan kemudian melakukan apa yang perlu Anda lakukan dengan objek yang dikembalikan.map
fokus pada aliran itu sendiri dan tidak dimaksudkan untuk "melakukan sesuatu ke objek lain tergantung pada status elemen ini dalam aliran". Baik untuk mengetahui yangifPresentOrElse
ditambahkan di Jawa 9.Alternatifnya adalah:
Saya tidak berpikir itu meningkatkan keterbacaan.
Atau seperti yang disarankan Marko, gunakan operator ternary:
sumber
new Object();
dengan lambda pertama Anda, tetapi jujur saja itu menjadi sangat jelek. Saya akan berpegang pada if / else untuk contoh Anda yang diperbarui.map
untuk hanya kembaliOptional
untuk merantai membuat kode lebih sulit untuk dipahami sementaramap
diasumsikan secara harfiah memetakan sesuatu.Solusi lain adalah dengan menggunakan fungsi tingkat tinggi sebagai berikut
sumber
value -> () -> syso
bagian itu.String result = opt.map(value -> "withOptional").orElse("without optional");
Tidak ada cara yang bagus untuk melakukannya di luar kotak. Jika Anda ingin menggunakan sintaks pembersih Anda secara teratur, maka Anda dapat membuat kelas utilitas untuk membantu:
Kemudian Anda dapat menggunakan impor statis di tempat lain untuk mendapatkan sintaks yang mendekati apa yang Anda cari:
sumber
Optional.ifPresentOrElse()
telah ditambahkan ke JDK 9.Jika Anda hanya dapat menggunakan Java 8 atau lebih rendah:
1) jika Anda tidak memiliki
spring-data
cara terbaik sejauh ini adalah:Sekarang saya tahu itu tidak mudah dibaca dan bahkan sulit dimengerti untuk seseorang, tetapi terlihat baik bagi saya secara pribadi dan saya tidak melihat cara lain yang lancar untuk kasus ini.
2) jika Anda cukup beruntung dan Anda dapat menggunakan
spring-data
cara terbaik adalah Opsional # ifPresentOrElse :Jika Anda dapat menggunakan Java 9, Anda harus menggunakan:
sumber
Perilaku yang dijelaskan dapat dicapai dengan menggunakan VAVR (sebelumnya dikenal sebagai Javaslang), perpustakaan fungsional-objek untuk Java 8+, yang mengimplementasikan sebagian besar konstruksi Scala (menjadi Scala bahasa yang lebih ekspresif dengan cara tipe sistem yang lebih kaya yang dibangun pada JVM). Ini adalah pustaka yang sangat bagus untuk ditambahkan ke proyek Java Anda untuk menulis kode fungsional murni.
Vavr menyediakan
Option
monad yang menyediakan fungsi untuk bekerja dengan jenis Opsi seperti:fold
: untuk memetakan nilai opsi pada kedua kasus (ditentukan / kosong)onEmpty
: memungkinkan untuk mengeksekusiRunnable
opsi ketika kosongpeek
: memungkinkan untuk mengkonsumsi nilai opsi (saat ditentukan).Serializable
sebaliknyaOptional
yang berarti Anda dapat menggunakannya dengan aman sebagai argumen metode dan anggota contoh.Opsi mengikuti hukum monad yang berbeda dengan "pseudo-monad" opsional Java dan menyediakan API yang lebih kaya. Dan tentu saja Anda dapat membuatnya dari Java's Optional (dan sebaliknya):
Option.ofOptional(javaOptional)
-Vavr berfokus pada interoperabilitas.Pergi ke contoh:
Bacaan lebih lanjut
Referensi kosong, kesalahan miliar dolar
NB Ini hanya sedikit contoh dari apa yang ditawarkan Vavr (pencocokan pola, stream alias daftar malas yang dievaluasi, tipe monadik, koleksi tidak berubah, ...).
sumber
Solusi lain dapat mengikuti:
Ini adalah bagaimana Anda menggunakannya:
Atau jika Anda dalam kasus penggunaan sebaliknya adalah benar:
Ini bahannya:
Antarmuka Fungsi yang ditingkatkan "secara kosmetik".
Dan kelas bungkus opsional untuk peningkatan:
Ini harus melakukan trik dan dapat berfungsi sebagai templat dasar bagaimana menangani persyaratan tersebut.
Ide dasar di sini adalah sebagai berikut. Dalam dunia pemrograman gaya non fungsional Anda mungkin akan menerapkan metode mengambil dua parameter di mana yang pertama adalah jenis kode runnable yang harus dieksekusi jika nilai tersedia dan parameter lainnya adalah kode runnable yang harus dijalankan jika nilai tidak tersedia. Demi keterbacaan yang lebih baik, Anda dapat menggunakan arus untuk membagi fungsi dua parameter menjadi dua fungsi masing-masing satu parameter. Inilah yang pada dasarnya saya lakukan di sini.
Petunjuk: Keikutsertaan juga menyediakan use case lain di mana Anda ingin mengeksekusi sepotong kode kalau-kalau nilainya tidak tersedia. Ini dapat dilakukan juga melalui Optional.filter.stuff tetapi saya menemukan ini jauh lebih mudah dibaca.
Semoga itu bisa membantu!
Pemrograman yang bagus :-)
sumber
Jika Anda ingin menyimpan nilai:
sumber
Misalkan Anda memiliki daftar dan menghindari
isPresent()
masalah (terkait dengan opsional) yang dapat Anda gunakan.iterator().hasNext()
untuk memeriksa jika tidak ada.sumber