Kullanım örnekleri
`` Optional`` s’in neden kullanıldığını öğrendiğimize göre, java’da neler yapabileceğimize bir göz atalım. Bu kod örnekleri (ve Sponge) Java 8’de bulunan`java.util.Optional <https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html>`_ sınıfını kullanmaktadır.
Sarılmış Değer Alma
get ()
yöntemi Optional
dosyasını açar ve paketlenmiş değeri döndürür. Hiçbir değer mevcut değilse, get ()
çağrısı bir
NoSuchElementException
atar, bu nedenle olup olmadığı kontrol edilmelidir.
Optional<String> opt = getOptionalString();
String wrappedString = opt.get();
Var olmayan Değerlerle Çalışma
Optional
türünün amacı, olabilecek veya olmayabilecek bir değeri temsil eder. Bu nedenle, birçok kullanım durumu, eksik değerleri işleme etrafında döner.
Varlık kontrolü
IsPresent ()
yöntemi, Optional
de bir değer mevcutsa true değerini döndürür. En temel doğrulamayı sağlayabilir ve klasik bir null
kontrolüne eşdeğerdir.
Optional<String> opt = getOptionalString();
if (opt.isPresent()) {
String wrappedString = opt.get();
// more code
}
Varsayılan Değerleri Kullanma
Ortak bir desen mevcut değilse varsayılan değere geri düşüyor. OrElse ()
yöntemi, Optional
de ya mevcut değeri ya da sağlanan varsayılan değeri döndürecek tek bir satır ifadesine izin verir.
Yerine
Optional<String> optionalString = getOptionalString();
String someString;
if (optionalString.isPresent()) {
someString = optionalString.get();
} else {
someString = DEFAULT_STRING;
}
sadece kullan
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.
Yerine
Optional<String> optionalString = getOptionalString();
String someString;
if (optionalString.isPresent()) {
someString = optionalString.get();
} else {
someString = myPlugin.defaultString();
}
sadece kullan
String someString = getOptionalString().orElseGet(myPlugin::defaultString);
Eksik değerler başarısız
Eksik olan bir değer bir istisnaya neden olursa, varsayılan “NoSuchElementException” a güvenmek yerine özel bir istisna atamak her zaman daha iyidir. VeyaElseThrow ()
yöntemini bir Supplier
ile çağırırsanız, sarılmış değeri varsa onu döndürür veya
Supplier``den alınan bir ``Throwable
atar. Yine, Supplier
fonksiyonel bir arayüz olduğunda lambda ifadeleri veya yöntem referansları kullanılabilir.
Yerine
Optional<String> optionalString = getOptionalString();
if (!optionalString.isPresent()) {
throw new MyException();
}
String someString = optionalString.get();
sadece kullan
String someString = getOptionalString().orElseThrow(MyException::new);
Not
Geliştirici tarafından sağlanan Throwablevv
, kontrol edilen bir istisna olduğu takdirde, çevredeki işlevin imzasına eklenecektir (örneğin, public void doStuff() throws MyException
)
Koşullu Kod Yürütme
Varsayılan değer kullanılamazsa, var olan bir değere dayanan kod çalıştırılamaz. Bu basit bir durumda ele alınabilirken, diğer uygun yöntemler vardır.
Tüketilen Değerler
Mevcut değeri işlemek için mantıklı bir Consumer
ya da tek bir parametre fonksiyonunda yapılandırılıyorsa, ifPresent () `` yöntemi kullanıcı (veya bir yöntem referansına) kabul edecektir. ``Optional
üzerinde bir değer varsa, kullanıcıya aktarılır.
Optional
boşsa, hiçbir şey olmaz.
Yerine
Optional<String> optionalString = getOptionalString();
if (optionalString.isPresent()) {
myPlugin.doSomethingWithString(optionalString.get());
}
sadece kullan
Optional<String> optionalString = getOptionalString();
optionalString.ifPresent(s -> myPlugin.doSomethingWithString(s));
veya
getOptionalString().ifPresent(myPlugin::doSomethingWithString);
Filtreleme
Ayrıca bir “Predicate” iletmek de mümkündür. Bu ‘’ Predicate ‘’ in yalnızca true değerini döndüren değerler korunacaktır. Herhangi bir değer mevcut değilse veya “İstek” terimi “false” ifadesini döndürürse boş bir ‘’ İsteğe bağlı ‘’ döndürülecektir. Bu yöntem isteğe bağlı döndürdüğünden, diğer yöntemlerle zincirleme yapılmasına izin verir.
Yerine
Optional<String> optionalString = getOptionalString();
if (optionalString.isPresent()) {
String someString = optionalString.get();
if (stringTester.isPalindromic(someString)) {
myPlugin.doSomethingWithString(someString);
}
}
sadece kullan
getOptionalString()
.filter(stringTester::isPalindromic)
.ifPresent(myPlugin::doSomethingWithString);
Not
Ne bu filtreleme işlevi ne de aşağıda açıklanan haritalama işlevleri çağrıldıkları örneği değiştirmez. ‘’ İsteğe bağlı’’ s değişmezdir.
Haritalama
Başka bir zincirlenebilir operasyon potansiyel değerin farklı bir haritalandırılmasıdır. Hiçbir değer mevcut değilse hiçbir şey değişmeyecek. Ancak, varsa, ‘’ map () ‘’ yöntemi, sağlanan “Fonksiyon” tarafından döndürülen değerin bir ‘’ İsteğe bağlı ‘’ döndürür (ya da bu dönüş değeri’ ‘null ‘’).
Yerine
Optional<String> optionalString = getOptionalString();
if (optionalString.isPresent()) {
String someString = optionalString.get().toLowerCase();
myPlugin.doSomethingWithString(someString);
}
sadece kullan
getOptionalString()
.map(s -> s.toLowerCase())
.ifPresent(myPlugin::doSomethingWithString);
Tüyo
Haritalama işlevi zaten bir ‘’ İsteğe bağlı ‘’ döndürürse bunun yerine ‘’ flatMap () ‘’ yöntemini kullanın. Haritalama işlevi zaten bir ‘’ İsteğe bağlı ‘’ döndürmesini beklediği ve dolayısıyla sonucu sarmamayacağı hariç, yalnızca ‘’ map () ‘’ gibi davranacaktır.
Kombine Örnek
Her oyuncunun bir evcil hayvan izlemesine izin veren bir eklenti düşünün. Aşağıdaki yöntemlerin varlığını varsayalım:
‘’ petRegistry.getPetForPlayer () ‘’ kabul etme ‘’ Oynatıcı ‘’ ve ‘’ İsteğe bağlı<Pet> ‘’ dönme. Bu yöntem, belirli bir oyuncuyla ilişkili hayvanı arar
‘’ petHelper.canSpawn () ‘’ bir ‘’ Pet ‘’ kabul ve ‘’ boolean ‘’ döndürme. Bu yöntem, verilen evcil hayvanların yumurtalandığından emin olmak için gerekli tüm kontrolleri yapar.
‘’ Pet Helper. Pet () ‘’ Pet ‘’ kabul ve hiçbir şey iade spawn. Bu yöntem, daha önce oluşturulmamış bir hayvan üretir.
Artık bir yerden (muhtemelen bir komutun yürütülmesi) ‘’ optionalPlayer’’ değişkenine bir ‘’ Optional<Player> ‘’ düzenliyoruz. Şimdi bu oyuncuların evcil hayvanlarını elde etmek, evcil hayvanların üretilip üretilmediğini kontrol etmek ve bunların üretilmediğini kontrol etmek istersek, her bir ‘’ İsteğe bağlı’’ nin gerçekten bir değer içerdiğini kontrol ederken bunu üretmek istiyoruz. Sadece temel ‘’ isPresent() ‘’ ve ‘’ get() ‘’ yöntemlerini kullanan kod gerçekten hızlı bir şekilde kötüleşir.
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);
Opsiyonlar Oluşturma
‘’ Null ‘’ değerlerini döndürmek yerine ‘’ Optional’’ kullanarak aynı sözleşmeyi takiben bir API sunmayı seçerseniz, bunları döndürebilmek için ‘’ Optional’’ s oluşturmanız gerekecektir. Bu, üç statik yapıcı yöntemden birini çağırarak yapılır.
‘’ Optional.empty () ‘’ daima boş bir ‘’ İsteğe bağlı ‘’ dönecektir.
‘’ Optional.of () ‘’ seçeneği verilen bir değeri sarmalamaya döndürür ve değer ‘’ null’’ ise bir ‘’ NullPointerException’’ değeri yükseltir.
‘’ Optional.ofNullable () ‘’, verilen değer ” ‘’ null’’ ise boş bir ‘’ İsteğe bağlı ‘’ döndürür, aksi takdirde ‘’ İsteğe bağlı ‘’ değeri sarmaya dönecektir.