2015-09-26 21 views
35

Bu yöntemlerin yürütme sırasını farklı olduğunu anlıyorum, ancak tüm testlerimde farklı sipariş yürütme gerçekleştiremiyorum.forEach ve forEachOrdered in Java 8 Stream

Örnek:

System.out.println("forEach Demo"); 
Stream.of("AAA","BBB","CCC").forEach(s->System.out.println("Output:"+s)); 
System.out.println("forEachOrdered Demo"); 
Stream.of("AAA","BBB","CCC").forEachOrdered(s->System.out.println("Output:"+s)); 

Çıkış: 2 yöntemleri farklı çıkışları olan zaman

forEach Demo 
Output:AAA 
Output:BBB 
Output:CCC 
forEachOrdered Demo 
Output:AAA 
Output:BBB 
Output:CCC 

örnekler verin.

+0

Paralel akışlarla deneyebilirsiniz. – Pshemo

+0

@Pshemo sadece bu olası bir seçenek midir? – gstackoverflow

+3

Belirtilmemiş sipariş “farklı düzende garanti” anlamına gelmez.Bu sadece * belirtilmemiş * anlamına gelir, bu da her zaman karşılaşma sırasına uyma olasılığını gösterir. Yerleşik shuffle işlevi yoktur. – Holger

cevap

42
Stream.of("AAA","BBB","CCC").parallel().forEach(s->System.out.println("Output:"+s)); 
Stream.of("AAA","BBB","CCC").parallel().forEachOrdered(s->System.out.println("Output:"+s)); 

ikinci hat olacaktır sipariş tutulmazsa çünkü ilk garantili buna karşın her zaman çıkış

Output:AAA 
Output:BBB 
Output:CCC 

. forEachOrdered, akışın sıralı mı yoksa paralel mi olduğuna bakılmaksızın, akışının elemanlarını, kaynağı tarafından belirtilen sırayla işler.

forEach Javadoc alıntı:

Bu operasyonun davranış, açıkça nondeterministic olduğunu. Paralel akımlı boru hatları için, bu işlem akışın karşılaşma düzenine saygı göstermeyi garanti etmez, çünkü bunu yapmak paralelliğin yararını feda eder.

forEachOrdered Javadoc durumları (vurgu benim): akışı belirli bir karşılaşma olduğunu kabul edersek

akımı karşılaşma amacıyla bu akımı, her bir elemanı için bir işlem gerçekleştirir.

+6

Evet, haklısınız. Sadece parallelStreams için mümkün mü? – gstackoverflow

+6

Sadece şu anda paralel akışlara uygulanacak olsa bile - ve bunu söylemiyorum - eğer bazı ara adımlar sıralanmamış akışlardan yararlanmak için optimize edilmişse, gelecekte de kırılabilir. akış sıralanmamışsa, bir sıralama kararsız bir algoritma kullanabilir. – the8472

+1

Bu yüzden "parallel" ile forEachOrdered'in kullanılması hiç mantıklı değil mi? –

20

forEach rağmen daha kısa ve güzel görünüyor, ben sipariş konularda açıkça bu belirtmek için nereye her yerde forEachOrdered kullanmayı öneririm. Sıralı akışlar için forEach, forEachOrdered'un kullanımı için semantik olarak gerekli olduğu sırayla, API iç kodu usesforEach (sıralı olduğu bilinen akış için) sırasına uymalı ve hatta akış gibi görünüyor! Yine de akışınızı paralel olarak değiştirmeye karar verebilirsiniz ve kodunuz kırılacaktır. Ayrıca, forEachOrdered kodunu kullandığınızda, kodunuzun okuyucusu mesajı görür: "sipariş burada önemlidir". Böylece kodunuzu daha iyi belgeliyor.

Paralel akışlar için forEach'un yalnızca deterministik olmayan sırada çalıştırılmasının yanı sıra farklı elemanlar için aynı anda (forEachOrdered ile mümkün olmayan) farklı iş parçacıklarında da çalıştırılabileceğini unutmayın. Son olarak hem forEach/forEachOrdered hem de nadiren faydalıdır. Durumların çoğunda aslında sadece bir yan etki değil, sonuç üretmek gerekir, bu nedenle reduce veya collect gibi işlemler daha uygun olmalıdır. forEach aracılığıyla doğaya yapılan işlemlerin azaltılmasının genellikle kötü bir stil olduğu düşünülmektedir.

+6

"Sonunda hem forEach/forEOrOrdered nadiren kullanışlıdır". Daha fazla katılıyorum. Bu yöntemler aşırı kullanılıyor gibi görünüyor. – Tunaki

+0

Cevabınız için teşekkürler. ama gerçek hayat örneği değil. Ben sadece java'yı öğrenirim. 8 – gstackoverflow

+0

Neden bu kodda 'forEachOrdered' kullanmak semantik olarak gereklidir? – RealSkeptic