Lambda ifadesi ve yöntem başvurusu [kapalı]


114

IntelliJ, lambda ifadelerimi yöntem referanslarıyla değiştirmemi önermeye devam ediyor.

İkisi arasında herhangi bir nesnel fark var mı?


4
Pek değil, herhangi bir nesne görmüyorum! Bana statik bir çağrı gibi görünüyor
Gerard

9
Elbette! Ama sen de bulamıyor musun ... Bu bir zevk meselesi, daha çok teknik açıdan endişelendim. Aslında, daha önce de söylediğin gibi, bu benim için iyi bir cevap. Her neyse, IntelliJ'in önerdiği gibi, sanırım bir yöntem referansını görmenin bir lambda'dan daha çok takdir edildiğini düşünüyorum (yine de benim için değil).
Gerard

15
Bir lambda ifadesinin kodu sentetik bir yönteme derlenirken, yöntem referansları olmadan çalışır (istisna: özel yapılar gibi Type[]::new). Çalışma zamanında oluşturulan anonim sınıf aynı olacaktır. JRE, aralarında herhangi bir fark yaratmaz. Dolayısıyla, bir yöntem referansı kullanmak, derlenmiş kodunuzda bir yöntemi kurtarır, diğer yandan, adım adım hata ayıklama yaparken bunlarda duramazsınız…
Holger

6
Şimdi soru kapatılacak ... Benim gibi lambdalar ile referanslar arasındaki farkı bilmeyen tüm kullanıcılar için çok kötü, kesin bir tane olmasa bile. Ayrıca neden kimse buna cevap vermeye cesaret edemediğini merak ediyorum. Bana doğru cevap bu.
Gerard

3
İki yıllık kapalı bir soruyu yanıtlamak muhtemelen kötü bir fikirdir, ancak soruyu GERÇEKTEN OKUYANLAR için Oracle'ın öğreticisi ( docs.oracle.com/javase/tutorial/java/javaOO/… ) şunu söylüyor: Yöntem referansları ... zaten bir ada sahip yöntemler için kompakt, okunması kolay lambda ifadeleri.
yarın

Yanıtlar:


187

Kesinlikle ihtiyacımız olmadığı halde, bu özelliği neden dile eklediğimiz konusunda biraz perspektif sunmama izin verin (tüm yöntemler referanslar lambdas olarak ifade edilebilir.)

Doğru cevabın olmadığını unutmayın . "Her zaman bir lambda yerine bir yöntem ref kullanın" veya "bir yöntem ref yerine her zaman bir lambda kullanın" diyen herkes göz ardı edilmelidir.

Bu soru, özünde "isimsiz bir sınıf yerine adlandırılmış bir sınıfı ne zaman kullanmalıyım" sorusuna çok benziyor? Cevap aynı: daha okunaklı bulduğunuzda . Kesinlikle biri veya kesinlikle diğeri olan durumlar vardır, ancak ortada bir sürü gri vardır ve yargı kullanılmalıdır.

Yöntem referanslarının arkasındaki teori basittir: isimler önemlidir . Bir yöntemin bir adı varsa, sonuçta sadece dönüp onu çağıran zorunlu bir kod torbası yerine adıyla ona atıfta bulunmak, genellikle (ama her zaman değil!) Daha açık ve okunabilirdir.

Performans veya karakter sayma hakkındaki tartışmalar çoğunlukla kırmızı ringa balığıdır ve onları görmezden gelmelisiniz. Amaç, ne yaptığını çok net bir şekilde yazmaktır. Çoğu zaman (ama her zaman değil!) Yöntem bu metriğe göre kazanımı ifade eder, bu nedenle bu durumlarda kullanılmak üzere bunları bir seçenek olarak dahil ettik.

Yöntemin amacı açıklığa kavuşturup yansıtmadığına dair önemli bir husus, temsil edilen işlevin şeklinin bağlamdan açık olup olmadığıdır. Bazı durumlarda (örneğin, map(Person::getLastName)bağlamdan bakıldığında, bir şeyi diğerine eşleyen bir işlevin gerekli olduğu oldukça açıktır ve bu gibi durumlarda, yöntem referansları parlar. fonksiyon tanımlanmaktadır; bu, bir lambda'nın daha uzun olsa bile daha okunabilir olabileceğine dair bir uyarı işaretidir.

Son olarak, bulduğumuz şey, çoğu insanın ilk başta yöntem referanslarından uzaklaştığı, çünkü lambdalardan daha yeni ve tuhaf hissettikleri ve bu nedenle başlangıçta onları "daha az okunabilir" bulduklarını, ancak zamanla sözdizimine alıştıklarında, genellikle davranışlarını değiştirirler ve yapabildiklerinde yöntem referanslarına yönelirler. Öyleyse, kendi öznel ilk "daha az okunabilir" tepkinizin neredeyse kesinlikle bir tür aile yanlılığını gerektirdiğinin farkında olun ve stilistik bir görüş sunmadan önce kendinize her ikisiyle rahatlama şansı vermelisiniz.


25
@Gerard Teşekkürler daha iyi bir cevap olabilirdi.
Yassin Hajaj

3
@Gerard Brian "Hayır, yok" diyor gibi geliyor
dj18

Brian, aynı yöntem için bir yöntem referansı ve bir lambda kullanarak farklı sonuçlar alıyorum. Değiştirilebilir olmaları gerekmez mi?
Michel Feinstein

@mFeinstein Her ref yöntemi için eşdeğer bir lambda vardır (kullanıyor olsanız da olmasanız da). Kodu soru olarak mı göndermek istiyorsunuz?
Brian Goetz

İstiyorum, ama korkarım ki kod çok büyük olabilir, çünkü LiveDataa içinde bir Android , a ile tetiklenen bir Android'e Fragmentdönüştürüyorum ... ve Android aynı duruma geri döndüğünde farklı davranışlar oluyor .. .bu yüzden onu bir soru için basitleştirmekte zorlanıyorumEventViewModelFragment
Michel Feinstein

10

Birkaç ifadeden oluşan uzun lambda ifadeleri kodunuzun okunabilirliğini azaltabilir . Böyle bir durumda, bu ifadeleri bir yöntemde ayıklamak ve ona referans vermek daha iyi bir seçim olabilir.

Diğer neden yeniden kullanılabilirlik olabilir . Lambda ifadenizi birkaç ifadeden kopyalayıp yapıştırmak yerine, bir yöntem oluşturabilir ve onu kodunuzun farklı yerlerinden çağırabilirsiniz.


3
Karşılaştırın: houses.map(House::getName)ve houses.map(h -> h.getName()). Lambda iki daha az karakter alır. Türün açık olmadığı doğrudur, ancak herhangi bir IDE size söyleyecektir ve ayrıca, tür açık olduğunda lambdalar kullanılmalıdır. Yeniden kullanılabilirlik konusunda sizinle aynı fikirde olabilirim, ancak lambdalar kesinlikle küçüktür, bu nedenle büyük özel yöntemler oluşturmak yerine zincirlenebilirler. Bu anlamda, küçük yöntemler bazı büyük ve karmaşık yöntemlerden daha fazla yeniden kullanılabilir ve lambdas'ın netliği (ve belirli bir dereceye kadar ayrıntı düzeyi) nedeniyle okunması hala kolaydır.
Gerard

11
Gerald'layım. Okunabilirlik aslında kodu çıkardığınızda zarar görür, bu yüzden okumaya devam etmek için ona atlamanız ve sonra geri dönmeniz gerekir. Sen istemek aynı yerde tüm ilgili koduna sahip olmaları. Ayrıca Houseçok iyi bir örnektir; peki ya ThreeStoryRedBrickHouseWithBlueDoors. Çoklu argümanlı lambdalar için yöntem referanslarını tercih ederim ve bazen lambda'nın yalnızca tek bir yöntem çağrısı hakkında olduğunu vurgulamayı tercih ederim. Bir yöntem referansında yanlış giden daha az şey vardır: kullanım sitesinde argümanı yanlış
yazabilir

@Gerard İlk ifadenize katılmıyorum. Yöntem adlarını iyi açıklarsanız ve büyük kod yığınları çıkarırsanız, kodun taşınması okunabilirliği artırır. Gizleyici yöntem isimleri kullanırsanız size katılıyorum.
Torsten
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.