Коллектор может быть использован для этого.
- Для двух категорий используйте
Collectors.partitioningBy()фабрику.
Это позволит создать Mapот Booleanдо List, и поставить элементы в один или другой список , основанный на Predicate.
Примечание. Поскольку поток должен потребляться целиком, он не может работать с бесконечными потоками. И поскольку поток все равно используется, этот метод просто помещает их в списки вместо создания нового потока с памятью. Вы всегда можете транслировать эти списки, если вам нужны потоки в качестве вывода.
Кроме того, нет необходимости в итераторе, даже в приведенном вами примере только для заголовков.
- Двоичное разбиение выглядит так:
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());
- Для большего количества категорий используйте
Collectors.groupingBy()фабрику.
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());
В случае, если потоки не являются Stream, но один из примитивных потоков, как IntStream, то этот .collect(Collectors)метод недоступен. Тебе придется делать это вручную, без коллекторской фабрики. Его реализация выглядит так:
[Пример 2.0 с 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 ));
});
В этом примере я инициализирую ArrayLists с полным размером исходной коллекции (если это вообще известно). Это предотвращает события изменения размера даже в худшем случае, но потенциально может поглотить пространство 2 * N * T (N = начальное количество элементов, T = количество потоков). Чтобы найти компромисс между скоростью и быстродействием, вы можете опустить его или использовать наиболее обоснованное предположение, например, ожидаемое наибольшее количество элементов в одном разделе (обычно чуть больше N / 2 для сбалансированного разделения).
Я надеюсь, что никого не оскорбляю, используя метод Java 9. Для версии Java 8 посмотрите историю изменений.
Streamв несколькоStreams без промежуточного преобразования , хотя я думаю, что люди, которые достигли этого вопроса, на самом деле ищут способ достичь этого, независимо от такого ограничения, что является ответом Марка. Это может быть связано с тем, что вопрос в заголовке не такой, как в описании .