Kolektor może być używany do tego celu.
- W przypadku dwóch kategorii użyj opcji
Collectors.partitioningBy()
factory.
Spowoduje to utworzenie Map
od Boolean
do List
i umieszczenie elementów na jednej lub drugiej liście w oparciu o Predicate
.
Uwaga: ponieważ strumień musi być zużyty w całości, nie może to działać w przypadku nieskończonych strumieni. A ponieważ strumień i tak jest zużyty, ta metoda po prostu umieszcza je na listach zamiast tworzyć nowy strumień z pamięcią. Zawsze możesz przesyłać strumieniowo te listy, jeśli potrzebujesz strumieni jako danych wyjściowych.
Nie ma też potrzeby stosowania iteratora, nawet w podanym przykładzie obejmującym tylko głowy.
- Podział plików binarnych wygląda następująco:
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());
- Aby uzyskać więcej kategorii, użyj
Collectors.groupingBy()
fabryki.
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());
W przypadku, gdy strumienie nie są Stream
, ale są jednym z strumieni pierwotnych, takich jak IntStream
, to ta .collect(Collectors)
metoda nie jest dostępna. Będziesz musiał to zrobić ręcznie bez fabryki kolektorów. Jego implementacja wygląda następująco:
[Przykład 2.0 od 16.04.2020]
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 ));
});
W tym przykładzie inicjalizuję ArrayLists pełnym rozmiarem początkowej kolekcji (jeśli w ogóle jest to znane). Zapobiega to zdarzeniom zmiany rozmiaru nawet w najgorszym przypadku, ale może potencjalnie pochłonąć 2 * N * T przestrzeni (N = początkowa liczba elementów, T = liczba wątków). Aby poświęcić miejsce na szybkość, możesz to pominąć lub wykorzystać swoje najlepsze przypuszczenia, takie jak oczekiwana najwyższa liczba elementów w jednej partycji (zwykle nieco ponad N / 2 dla zrównoważonego podziału).
Mam nadzieję, że nikogo nie obrażam, używając metody Java 9. W przypadku wersji Java 8 spójrz na historię edycji.
Stream
na wieleStream
s bez konwersji pośredniej , chociaż myślę, że ludzie, którzy dotarli do tego pytania, faktycznie szukają sposobu, aby to osiągnąć, niezależnie od takiego ograniczenia, co jest odpowiedzią Marka. Może to wynikać z faktu, że pytanie w tytule nie jest takie samo jak w opisie .