SORU
19 Mayıs 2013, Pazar


Java 8 İterable.() forEach vs foreach döngü

Aşağıdakilerden hangisi Java 8'de daha iyi bir uygulamadır?

Java8:

joins.forEach((join) -> mIrc.join(mSession, join));

Java7:

for (String join : joins) {
    mIrc.join(mSession, join);
}

""Lambda, ama gerçekten performansı ve okunabilirliği de dahil olmak üzere bunları kullanarak herhangi bir avantajı var mı? ile basitleştirilmiş olabilir döngüler için bir sürü var

EDİT

Ben de uzatmak bu soruya uzun yöntemleri - biliyorum cant dönüş ya da sonu ana işlevi lambda ve bunun olması söz konusu olduğunda karşılaştırıldığında, ama başka bir şey var dikkat edilmesi gereken?

CEVAP
24 Kasım 2013, Pazar


Daha iyi uygulama for-each kullanmaktır. Bu Basit Tutun ihlal üstelik Aptalca prensibi, yeni-moda forEach() en az aşağıdaki eksiklikleri vardır:

  • Kullanımı nihai olmayan değişkenler. Bu yüzden, aşağıdaki gibi bir kod dosyalarda grup lambda dönüştürülebilir mi:

    Object prev = null;
    for(Object curr : list)
    {
        if( prev != null )
            foo(prev, curr);
        prev = curr;
    }
    
  • Kontrol özel durumlar işleyebilir. Lambda aslında kontrol bloklarından yasak değil, ama Consumer gibi ortak fonksiyonel arayüzleri herhangi bir beyan yok. Bu nedenle, kontrol özel durum oluşturduğunda başka herhangi bir kod try-catch Throwables.propagate() sarın gerekir. Ama eğer o yoksa bile, her zaman atılan özel durum ne olur belli değil. Bir yere forEach() bu süre zarfında yutmuş olabilir

  • Sınırlı denetim akışı. Lambda return-her bir continue eşittir, ama break bir eşdeğeri yoktur. Ayrıca zor dönüş değerleri, kısa devre gibi şeyler var yaset bayraklareğer bu ihlal olmasaydı . işler biraz alieviated, olan ( ^em>nihai olmayan hiçbir değişkenkuralı). "This is not just an optimization, but critical when you consider that some sequences (like reading the lines in a file) may have side-effects, or you may have an infinite sequence."

  • Buna paralel olarak yürütebilirbir korkunç , korkunç optimize edilmiş. olması gereken kod ama 0.1% her şey için Herhangi bir paralel kod kilitleri, uçucular, ve çok iş parçacıklı geleneksel yürütme özellikle kötü diğer yönleri değil ise bile () düşünülmüş olmalı. Herhangi bir hata bulmak zor olacak.

  • Performans zarar verebilirbu JİT dosyalarda grup optimize etmek için() döngüler, özellikle Lambda yeni olduğunu şimdi net gördüm. aynı ölçüde lambda ""Modern JİT derleyici kod çalıştıran gerçekleştiren gelişmiş analiz ve dönüşüm için Lambda küçük olan) arıyorum, ama. yükü anlamına gelmez optimizasyon tarafından

  • Eğer bir paralellik varsa, muhtemelen çok daha hızlı ve çok daha fazla bir ExecutorService kullanmak zor değil. Akışları otomatik ve sihirli (okuma: senin sorunun hakkında pek bir şey yokveuzman (genel durum) için verimsiz paralellik stratejisi (çatal-katıl özyinelemeli bozunma) kullanın.

  • Hata ayıklama daha karmaşık hale getiririç içe çağrı hiyerarşisi ve , Tanrı korusun, çünkü, infaz paralel. Hata ayıklayıcı çevreleyen kod gösteren değişkenler sorunları olabilir, ve adım gibi işler beklendiği gibi çalışmayabilir.

  • Sopalarla bir Boğaz başparmak gibi dışarı. Java dili için-her statetement vardır. Neden bir işlev çağrısı ile değiştirin? Neden ifadelerde yan etkileri bir yerlerde saklanıyor teşvik? Neden hantal bir-gömlekleri teşvik? -Her yeni istesekte istemesekte normal dosyalarda grup karıştırma kötü bir üslup. Kod lazım konuş cümleler (desen, o daha çabuk kavrar nedeniyle tekrarlama) ve daha az cümleler kullanılır net Kodu ve daha az zaman harcıyor karar verirken hangi tabiri kullanmak için büyük bir zaman boşaltmak için mükemmelliyetçi gibi kendimi!).

Gördüğünüz gibi, bu dosyalarda grup büyük bir hayranı değilim() mantıklı durumda.

Bana özellikle saldırgan Stream Iterable uygulamak için-her bir kullanılan olamaz değil aslında, sadece bir forEach(). Bu yüzden bana değil fathomable. (Kesinlikle C#'ın tasarımcıları gerekli olduğunu düşünmüyordu.) İterables stream.collect(Collectors.toList()) stream.toArray( T[]::new ) kullanarak Akarsu zorlama ve for-each ile onları kullanmanızı tavsiye ederimEdit: Aynı zamanda for(T element : (Iterable<T>)stream::iterator) ile bir İterable o görünebilir gibi şaşırtıcı olarak () içine akışını zorlamak için.

Bu, forEach() aşağıdakiler için yararlıdır " dedi

  • Atomik senkronize bir liste içinde dolaşmak. Bundan önce, bir liste Collections.synchronizedList() ile oluşturulan ve get veya set gibi şeyler için saygı ile atom oldu, ama yineleme zaman güvenli iş parçacığı değildi.

  • Yürütme (uygun paralel bir akış kullanarak) paralel. Bu sorunu performans varsayımlar Dere ve Spliterators yerleşik eşleşirse kod vs birkaç satır bir ExecutorService kullanarak kaydeder.

  • Hangi özel kaplarsenkronize listesi gibi, yineleme bu insanlar daha fazla örnek getirebilir sürece büyük ölçüde teorik olsa da kontrolü elinde tutmaya yarar

  • Tek bir işlevi daha temiz bir şekilde arıyorforEach() ve yöntem bir referans kullanarak değişken, list.forEach (obj::someMethod) yani). Ancak, akılda tutulması kontrol istisnaları puan, daha zor hata ayıklama ve cümleler sayısını azaltarak kod yazarken kullanın.

Makaleler referans için kullanılabilir:

DÜZENLEME:Lambda için orijinal önerilerden bazıları gibi görünüyor (http://www.javac.info/closures-v06a.html), bahsettiğim sorunların bir sürü kendi komplikasyonları, elbette eklerken () çözüldü.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • kidrauhl

    kidrauhl

    15 Ocak 2007
  • mliskIT

    mliskIT

    29 Mart 2012
  • TantalizingTrance

    TantalizingT

    15 ŞUBAT 2009