Contoh penggunaan
Sekarang yang kita pelajari mengapa Optional
s digunakan, mari kita lihat apa yang sebenarnya dapat kita lakukan dengannya di java. Contoh kode ini (dan Sponge) menggunakan java.util.Optional kelas tersedia di Java 8.
Mendapatkan Nilai terbungkus
The get()
method will unwrap an Optional
and return the wrapped value. If no value is present, calling get()
will throw a NoSuchElementException
, so a presence check should be performed first.
Optional<String> opt = getOptionalString();
String wrappedString = opt.get();
Gagal pada nilai absen
Tujuan dari tipe `` Opsional` mewakili nilai yang mungkin atau mungkin tidak ada di sana. Dengan demikian, banyak kasus penggunaan berkisar pada penanganan nilai absen.
Memeriksa Kehadiran
Metode `` isPresent () `` mengembalikan nilai true jika ada pada `` Opsional``. Ini bisa memberikan verifikasi yang paling dasar dan setara dengan cek klasik `` null``.
Optional<String> opt = getOptionalString();
if (opt.isPresent()) {
String wrappedString = opt.get();
// more code
}
Gunakan Nilai Default
Pola umum adalah yang jatuh kembali ke harga default jika tidak ada yang hadir. Metode orElse()
mengizinkan laporan satu baris yang akan mengembalikan harga yang ada pada Optional
atau harga default yang diberikan.
Melainkan
Optional<String> optionalString = getOptionalString();
String someString;
if (optionalString.isPresent()) {
someString = optionalString.get();
} else {
someString = DEFAULT_STRING;
}
gunakan saja
String someString = getOptionalString().orElse(DEFAULT_STRING);
In some cases, a default value has to be calculated in a way that has side effects or is particularly expensive. In such
a case it is desirable to calculate the default value only if needed (lazy evaluation). The orElseGet()
method
accepts a Supplier
instead of a pre-calculated value. If no value is present on the Optional
itself, the
Supplier
will be called. Since Supplier
is a functional interface, a lambda expression or method reference can
be passed instead.
Melainkan
Optional<String> optionalString = getOptionalString();
String someString;
if (optionalString.isPresent()) {
someString = optionalString.get();
} else {
someString = myPlugin.defaultString();
}
gunakan saja
String someString = getOptionalString().orElseGet(myPlugin::defaultString);
Gagal pada nilai absen
Jika nilai yang absen harus mengarah pada pengecualian, hampir selalu lebih baik untuk membuang pengecualian khusus alih-alih mengandalkan kembali `` NoSuchElementException``. Jika Anda memanggil metode `` orElseThrow () `` dengan `` Supplier``, itu akan mengembalikan nilai terbungkus jika ada, atau melempar `` Throwable`` yang diperoleh dari `` Supplier`` jika ` Opsional kosong Sekali lagi, sebagai `` Pemasok` adalah antarmuka fungsional, lambda cepat atau referensi metode dapat digunakan sebagai gantinya.
Melainkan
Optional<String> optionalString = getOptionalString();
if (!optionalString.isPresent()) {
throw new MyException();
}
String someString = optionalString.get();
gunakan saja
String someString = getOptionalString().orElseThrow(MyException::new);
Catatan
Jika '' Throwable'' disediakan oleh pemasok diperiksa pengecualian, itu juga harus disertakan dalam tanda tangan dari fungsi sekitarnya (untuk contoh '' doStuff() Batal umum melempar MyException'')
Eksekusi Kode Bersyarat
Jika tidak ada nilai default yang bisa digunakan, kode yang bergantung pada nilai yang ada tidak bisa di eksekusi. Meskipun hal ini mungkin ditangani dalam kondisi sederhana, ada metode lain yang mudah digunakan.
Mengkonsumsi Nilai
Jika logika Anda untuk menangani nilai sekarang sudah dienkapsulasi dalam fungsi `` Konsumen`` atau fungsi satu parameter, metode `` ifPresent () `` akan menerima konsumen (atau referensi metode). Jika ada nilai pada `` Opsional`, maka akan diteruskan ke konsumen. Jika `` Opsional` kosong, tidak akan terjadi apa-apa.
Melainkan
Optional<String> optionalString = getOptionalString();
if (optionalString.isPresent()) {
myPlugin.doSomethingWithString(optionalString.get());
}
gunakan saja
Optional<String> optionalString = getOptionalString();
optionalString.ifPresent(s -> myPlugin.doSomethingWithString(s));
atau
getOptionalString().ifPresent(myPlugin::doSomethingWithString);
Penyaringan
Hal ini juga mungkin untuk melewati sebuah '' predikat ''. Hanya nilai-nilai yang '' predikat '' ini mengembalikan true untuk akan disimpan. Jika tidak ada nilai hadir atau '' predikat '' kembali '' palsu '', kosong '' opsional '' akan dikembalikan. Karena metode ini mengembalikan opsional, memungkinkan untuk chaining dengan metode lain.
Melainkan
Optional<String> optionalString = getOptionalString();
if (optionalString.isPresent()) {
String someString = optionalString.get();
if (stringTester.isPalindromic(someString)) {
myPlugin.doSomethingWithString(someString);
}
}
gunakan saja
getOptionalString()
.filter(stringTester::isPalindromic)
.ifPresent(myPlugin::doSomethingWithString);
Catatan
Baik ini fungsi penyaringan atau fungsi pemetaan yang dijelaskan di bawah ini memodifikasi instance yang mereka dipanggil. Optional
s selalu tidak berubah.
Pemetaan
Operasi berantai lainnya adalah pemetaan nilai potensial ke salah satu yang berbeda. Jika tidak ada nilai yang dihasilkan, tidak ada yang akan berubah. Namun jika ada, peta()
metode akan kembali sebagai Opsional
dari nilai yang dikembalikan dari Function
seharusnya (atau Opsional
kosong jika nilai yang dikembalikan adalah null
).
Melainkan
Optional<String> optionalString = getOptionalString();
if (optionalString.isPresent()) {
String someString = optionalString.get().toLowerCase();
myPlugin.doSomethingWithString(someString);
}
gunakan saja
getOptionalString()
.map(s -> s.toLowerCase())
.ifPresent(myPlugin::doSomethingWithString);
Tip
Jika fungsi pemetaan Anda sudah mengembalikan `` Opsional``, gunakan metode `` flatMap () `` sebagai gantinya. Ini akan berperilaku seperti `` map () ``, kecuali bahwa mereka mengharapkan fungsi pemetaan untuk mengembalikan `` Opsional` dan karena itu tidak akan membungkus hasilnya.
Contoh Gabungan
Bayangkan sebuah plugin yang memungkinkan setiap pemain untuk memiliki hewan peliharaan berikut. Asumsikan adanya metode berikut:
`` petRegistry.getPetForPlayer () `` menerima `` Player`` dan mengembalikan sebuah `` Opsional <Pet> ``. Metode ini mencari hewan peliharaan yang terkait dengan pemain yang diberikan
`` petHelper.canSpawn () `` menerima `` Pet`` dan mengembalikan `` boolean``. Metode ini melakukan semua pemeriksaan yang diperlukan untuk memastikan hewan peliharaan yang diberikan bisa melahirkan.
`` petHelper.spawnPet () `` menerima `` Pet`` dan tidak mengembalikan apapun. Cara ini akan menelurkan hewan peliharaan yang sebelumnya tidak bertelur.
Sekarang dari suatu tempat (mungkin eksekusi perintah) kita mendapatkan variabel `` optionalPlayer` yang memegang Opsional <Player> . Kami sekarang ingin mendapatkan hewan peliharaan pemain ini, memeriksa apakah hewan peliharaan tersebut melahirkan dan jika tidak melahirkan, menelurkannya saat melakukan pemeriksaan yang sesuai jika masing-masing dan setiap `Opsional sebenarnya mengandung nilai. Kode hanya menggunakan metode `` isPresent () `` dan `` get () `` dasar menjadi sangat buruk dengan sangat cepat.
if (optionalPlayer.isPresent()) {
Player player = optionalPlayer.get();
Optional<Pet> optionalPet = petRegistry.getPetForPlayer(player);
if (optionalPet.isPresent()) {
Pet pet = optionalPet.get();
if (petHelper.canSpawn(pet)) {
petHelper.spawnPet(pet);
}
}
}
However, through the use of Optional
methods for conditional code execution, all those presence checks are hidden,
reducing the boilerplate and indentation levels and thus leaving the code much more readable:
optionalPlayer
.flatMap(petRegistry::getPetForPlayer)
.filter(petHelper::canSpawn)
.ifPresent(petHelper::spawnPet);
Membuat Pilihan
Jika Anda memilih untuk memberikan API mengikuti kontrak yang sama dengan menggunakan `` Opsional` daripada mengembalikan nilai `` null``, Anda harus membuat `` Opsional`` untuk mengembalikannya. Hal ini dilakukan dengan memanggil salah satu dari tiga metode konstruktor statis.
`` Opsional.empty () `` akan selalu kembali kosong `` Opsional``.
`` Opsional.of () `` akan mengembalikan pembungkus opsional nilai yang diberikan dan meningkatkan `` NullPointerException`` jika nilainya `` null``.
`` Opsional.ofNullable () `` akan mengembalikan 'Opsional' kosong 'jika nilai yang diberikan adalah `` null``, jika tidak maka akan mengembalikan `` Opsional` `yang membungkus nilainya.