Для цього може бути використаний колектор .
- Для двох категорій використовуйте
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
в декількаStream
s без проміжного перетворення , хоча я думаю, що люди, які дійшли до цього питання, насправді шукають спосіб досягти цього незалежно від такого обмеження, що є відповіддю Марка. Це може бути пов’язано з тим, що питання в заголовку не таке, як у описі .