Bunun için bir toplayıcı kullanılabilir.
- İki kategori için
Collectors.partitioningBy()
fabrika kullanın .
Bu, bir Map
from Boolean
ila oluşturur List
ve öğeleri a veya diğer listeye a Predicate
.
Not: Akışın bütün olarak tüketilmesi gerektiğinden, bu sonsuz akışlarda çalışamaz. Akış yine de tüketildiği için, bu yöntem onları bellekle yeni bir akış yapmak yerine listelere koyar. Çıktı olarak akışa ihtiyacınız varsa bu listeleri her zaman aktarabilirsiniz.
Ayrıca, yinelemeye gerek yok, sağladığınız sadece kafa örneğinde bile.
- İkili bölme şöyle görünür:
Random r = new Random();
Map<Boolean, List<String>> groups = stream
.collect(Collectors.partitioningBy(x -> r.nextBoolean()));
System.out.println(groups.get(false).size());
System.out.println(groups.get(true).size());
- Daha fazla kategori için bir
Collectors.groupingBy()
fabrika kullanın .
Map<Object, List<String>> groups = stream
.collect(Collectors.groupingBy(x -> r.nextInt(3)));
System.out.println(groups.get(0).size());
System.out.println(groups.get(1).size());
System.out.println(groups.get(2).size());
Akarsuların olmaması Stream
, ancak ilkel akarsulardan biri olması durumunda IntStream
, bu .collect(Collectors)
yöntem mevcut değildir. Bir kollektör fabrikası olmadan manuel olarak yapmanız gerekecek. Bu uygulama şöyle görünür:
[Örnek 2020-04-16'dan beri 2.0]
IntStream intStream = IntStream.iterate(0, i -> i + 1).limit(100000).parallel();
IntPredicate predicate = ignored -> r.nextBoolean();
Map<Boolean, List<Integer>> groups = intStream.collect(
() -> Map.of(false, new ArrayList<>(100000),
true , new ArrayList<>(100000)),
(map, value) -> map.get(predicate.test(value)).add(value),
(map1, map2) -> {
map1.get(false).addAll(map2.get(false));
map1.get(true ).addAll(map2.get(true ));
});
Bu örnekte ArrayLists'i ilk koleksiyonun tam boyutuyla başlatırım (bu zaten biliniyorsa). Bu, en kötü senaryoda bile yeniden boyutlandırma olaylarını önler, ancak potansiyel olarak 2 * N * T alanını artırabilir (N = ilk öğe sayısı, T = iş parçacığı sayısı). Alanı hız için takas etmek için, bir bölümdeki beklenen en yüksek sayıda öğe gibi (genellikle dengeli bir bölünme için N / 2'nin üzerinde) olduğu gibi, dışarıda bırakabilir veya en iyi eğitimli tahmininizi kullanabilirsiniz.
Umarım bir Java 9 yöntemi kullanarak kimseyi incitmezim. Java 8 sürümü için düzenleme geçmişine bakın.
Stream
birden çokStream
s'ye dönüştürme olasılığına odaklanmış olsa da, bu soruya ulaşan insanların aslında Mark'ın cevabı olan bu kısıtlamadan bağımsız olarak bu yolu elde etmenin yolunu aradıklarını düşünüyorum. Bu , başlıktaki sorunun açıklamadakiyle aynı olmaması nedeniyle olabilir .