Normal indirgeme, int, double, vb. Gibi iki değişmez değeri birleştirmek ve yeni bir değer üretmek içindir; bir var değişmez azalma. Buna karşılık, toplama yöntemi, üretmesi beklenen sonucu biriktirmek için bir kabı mutasyona uğratacak şekilde tasarlanmıştır .
Sorunu göstermek için, Collectors.toList()
basit bir azaltma kullanarak elde etmek istediğinizi varsayalım.
List<Integer> numbers = stream.reduce(
new ArrayList<Integer>(),
(List<Integer> l, Integer e) -> {
l.add(e);
return l;
},
(List<Integer> l1, List<Integer> l2) -> {
l1.addAll(l2);
return l1;
});
Bu eşdeğerdir Collectors.toList()
. Ancak, bu durumda mutasyona uğrarsınız List<Integer>
. Bildiğimiz gibi ArrayList
, iş parçacığı için güvenli değil veya yineleme sırasında değer eklemek / çıkarmak güvenli değildir, böylece ArrayIndexOutOfBoundsException
listeyi veya birleştiriciyi güncellediğinizde eşzamanlı istisna veya herhangi bir istisna (özellikle paralel çalıştırıldığında) elde edersiniz. tamsayıları toplayarak (ekleyerek) listeyi değiştirdiğiniz için listeleri birleştirmeye çalışır. Bu iş parçacığını güvenli hale getirmek istiyorsanız, her seferinde performansı düşürecek yeni bir liste geçirmeniz gerekir.
Buna karşılık, Collectors.toList()
benzer şekilde çalışır. Ancak, değerleri listede biriktirdiğinizde iplik güvenliğini garanti eder. Gönderen belgelerine collect
yöntemiyle :
Bir Toplayıcı kullanarak bu akışın elemanları üzerinde değiştirilebilir bir azaltma işlemi gerçekleştirir. Akış paralelse ve Toplayıcı eşzamanlıysa ve ya akış sıralanmamışsa ya da toplayıcı sıralanmamışsa, eşzamanlı bir azalma gerçekleştirilir. Paralel olarak yürütüldüğünde, değiştirilebilir ara yapıların izolasyonunu sürdürmek için çoklu ara sonuçlar başlatılabilir, doldurulabilir ve birleştirilebilir. Bu nedenle, iş parçacığı için güvenli olmayan veri yapılarına (ArrayList gibi) paralel olarak yürütüldüğünde bile, paralel azaltma için ek senkronizasyon gerekmez.
Sorunuzu cevaplamak için:
collect()
Vs ne zaman kullanılır reduce()
?
Aşağıdaki gibi değişmez değerleri varsa ints
, doubles
, Strings
o zaman normal bir azalma sadece para cezası çalışır. Bununla birlikte, reduce
değerlerinizi bir List
(değiştirilebilir veri yapısı) olarak söylemek zorundaysanız , collect
yöntemle değiştirilebilir azaltmayı kullanmanız gerekir .