Her zaman doğru olan dahili Java 8 koşulu?


129

Google Guava'nın her zaman geri dönentrue bir koşulu vardır . Java 8'in benzer bir özelliği var Predicatemı? Kullanabileceğimi biliyorum (foo)->{return true;}, ama önceden yapılmış, buna benzer bir şey istiyorum Collections.emptySet().

Yanıtlar:


162

Java 8'de yerleşik her zaman doğru ve her zaman yanlış yüklemler yoktur. Bunları yazmanın en kısa yolu

x -> true

ve

x -> false

Bunları şununla karşılaştırın:

Predicates.alwaysTrue() // Guava

ve son olarak anonim bir iç sınıfa:

new Predicate<Object>() {
    public boolean test(Object x) {
        return true;
    }
}

Muhtemelen Guava'nın bu yerleşik yüklemlere sahip olmasının nedeni, anonim bir iç sınıfa göre statik bir yöntem çağrısının büyük bir sözdizimsel avantajının olmasıdır. Java 8'de, lambda sözdizimi o kadar kısadır ki, statik bir yöntem çağrısı yazmanın sözdizimsel bir dezavantajı vardır .

Bu sadece sözdizimsel bir karşılaştırma. x -> trueBirden çok sınıfa yayılan ve her biri kendi yüklem örneğini yaratan olaylarla karşılaştırıldığında, tek bir global her zaman doğru yüklem olsaydı, muhtemelen küçük bir alan avantajı vardır . Endişelendiğin bu mu? Tasarruflar ikna edici görünmüyordu, bu yüzden muhtemelen ilk etapta eklenmemişlerdi. Ancak gelecekteki bir sürüm için yeniden değerlendirilebilir.

GÜNCELLEME 2015-04-24

Biz, statik çeşitli eklenmesi gibi adlandırılmış işlevleri kabul ettik Predicate.alwaysTrue, Runnable.noopvb, ve biz Java SE gelecekteki sürümlerinde artık eklemeye karar verdik.

Kesinlikle yazılı bir lambda'ya karşı bir ada sahip bir şeyde bir değer vardır, ancak bu değer oldukça küçüktür. Biz insanların okuma ve yazma öğrenmek bekliyoruz x -> trueve () -> { }ve kullanım deyimsel olacağını söyledi. Hatta değeri Function.identity()over x -> xsorgulanabilir.

Yazılı bir lambda'yı değerlendirmek yerine mevcut bir işlevi yeniden kullanmanın küçük bir performans avantajı vardır, ancak bu tür işlevlerin kullanımının o kadar küçük olmasını bekleriz ki böyle bir avantaj ihmal edilebilir, kesinlikle API bloatına değmez.

Holger, yorumlarında, Predicate.orve benzeri birleşik işlevleri optimize etme olasılığından da bahsetti . Bu da dikkate alındı ​​( JDK-8067971 ), ancak biraz kırılgan ve hataya açık olarak görüldü ve uygulama çabasına değmeyecek kadar nadiren meydana geldi.

Ayrıca bu Lambda SSS girişine bakın.


14
İki endişe: Birincisi kısalık. Eğer (foo)->{return true;}yapabileceğim en iyisi, ben daha iyi istiyorum. Ama sen büyüdün x->true, bu çok daha iyi ve ilk sorunu hafifletiyor. İkinci konu, mantık ve statik bildirimdir. Ben kullanırsanız x->true, farkında olmadan (örneğin mahveder, hangi hala mantık dahil olduğu x->!true). Ancak Predicate.alwaysTrue(), yalnızca bir veya iki benzer yöntem olduğu için mantık hatası için sıfır yer vardır. Ayrıca IDE kodunu ücretsiz olarak tamamlıyorum. x->trueneredeyse iyi, ancak yine de Predicate.alwaysTrue()yukarıdaki nedenlerden dolayı bir yöntem yazdım .
Garret Wilson

10
@GarretWilson Ama Predicate.alwaysTrue()seninle kazara yazarak da hata yapabilirsin Predicate.alwaysFalse().
David Conrad

5
@DavidConrad, tabii ki. Her zaman hata yapabileceğim yollar vardır ve aslında sürekli yenilerini icat ediyorum. ;) Burada önemsiz bir şey üzerine bir tartışma başlatmak istemiyorum, ancak şunu söyleyeyim, statik bir yöntem referansı ile sadece iki seçenekle sınırlı bir kelime dağarcığım var: alwaysTrue()ve alwaysFalse(). Gerçek lambda ile birçok varyasyonum var; Her seferinde formülü esasen yeniden oluşturuyorum. Özünde, alwaysTrue()yapmak istediğim şey için anlamsal bir etikettir; x->trueaslında bunu her seferinde yeniden yapıyor. Çok büyük değil, ama dikkate değer.
Garret Wilson

25
Onanmış bir büyük avantajı Predicate.alwaysTrue()ve Predicate.alwaysFalse()örnekleri onlar gibi yöntemler birleştirilerek kabul edilebilir yani, Predicate.or, Predicate.and, ve Predicate.negate(). Bu, ek yük olmadan yoluyla birleştirerek Predicatedeğişkenleri önceden başlatmaya alwaysTrue()ve tahminler eklemeye izin verir and. Lambda ifadelerinin nesne kimliği garantisi olmadığı için, bu başarısız olabilir x->true. Bu arada, metodu Xolan bir sınıfım varsa , kullanmak gerçekten önerilenden daha kısa ama gerçekten tavsiye edilmiyor…staticy(){return true;}X::yx->true
Holger

10
Deyimin x -> truedezavantajı bir değişkeni kullanmadan kullanmam gerekmesidir. Bu, gereksiz beyin yükü ve ayrıca IDE'mde bir uyarı yaratır. Kullanmaya çalıştım _ -> trueama bu bir sözdizimi hatası. Java'da "kullanılmayan parametre" için kesinlikle bir anahtar sözcük (okuyun: keyletter) eksik. Umarım Java 9'da böyle bir şey gelir (veya en azından: Java ölmeden önce ne olursa olsun ^^)
kap

4

Guava olmadan

Boolean.TRUE::booleanValue

3
İlginç. İsteğin ruhunu tamamen yakalayıp yakalamadığından emin değilim, ancak yaratıcılık için puan alıyor!
Garret Wilson

21
Ama Predicatebir tartışma gerektirmediği için bir değil.
Florent Guillaume

1
Bu bir yüklem değildir, bir yöntem referansıdır, ancak özlü olma ve kullanılmayan bir parametreden bahsetmeye zorlamama erdemine sahiptir. +1 Bu arada, ciddi bir modülerlik sorunu olan Guava'yı kullanmaktan kaçındığı için, benim olumlu oyumu hak ediyor;)
gouessej

16
Kişisel yöntem referansı Tedarikçi <Boolean> atanabilir ama değil Yüklem <T>
Daniel K.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.