Seorang kolektor dapat digunakan untuk ini.
- Untuk dua kategori, gunakan
Collectors.partitioningBy()
pabrik.
Ini akan membuat Map
dari Boolean
ke List
, dan meletakkan item dalam satu atau daftar lain berdasarkan a Predicate
.
Catatan: Karena aliran perlu dikonsumsi keseluruhan, ini tidak dapat bekerja pada aliran yang tak terbatas. Dan karena aliran dikonsumsi pula, metode ini hanya menempatkan mereka di Daftar daripada membuat aliran-dengan-memori baru. Anda selalu dapat melakukan streaming daftar tersebut jika Anda membutuhkan streaming sebagai output.
Juga, tidak perlu untuk iterator, bahkan tidak dalam contoh head-only yang Anda berikan.
- Pemisahan biner terlihat seperti ini:
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());
- Untuk kategori lainnya, gunakan
Collectors.groupingBy()
pabrik.
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());
Jika aliran tidak Stream
, tetapi salah satu aliran primitif suka IntStream
, maka .collect(Collectors)
metode ini tidak tersedia. Anda harus melakukannya dengan cara manual tanpa pabrik pengumpul. Implementasinya terlihat seperti ini:
[Contoh 2.0 sejak 2020-04-16]
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 ));
});
Dalam contoh ini saya menginisialisasi ArrayLists dengan ukuran penuh dari koleksi awal (jika ini diketahui sama sekali). Ini mencegah mengubah ukuran peristiwa bahkan dalam skenario terburuk, tetapi berpotensi dapat melahap ruang 2 * N * T (N = jumlah elemen awal, T = jumlah utas). Untuk menukar ruang untuk kecepatan, Anda dapat meninggalkannya atau menggunakan tebakan terbaik Anda, seperti jumlah elemen tertinggi yang diharapkan dalam satu partisi (biasanya lebih dari N / 2 untuk pemisahan seimbang).
Saya harap saya tidak menyinggung siapa pun dengan menggunakan metode Java 9. Untuk versi Java 8, lihat pada edit history.
Stream
ke beberapaStream
s tanpa konversi menengah , meskipun saya pikir orang-orang yang mencapai pertanyaan ini benar-benar mencari jalan untuk mencapai sehingga terlepas dari kendala tersebut, yang merupakan jawaban Markus. Ini mungkin karena fakta bahwa pertanyaan dalam judul tidak sama dengan yang ada dalam deskripsi .