Этот "> ответ предоставляет реализацию для разбиения IntStream:
IntStream intStream = IntStream.iterate(0, i -> i + 1).limit(1000000);
Predicate<Integer> p = x -> r.nextBoolean();
Map<Boolean, List<Integer>> groups = intStream.collect(() -> {
Map<Boolean, List<Integer>> map = new HashMap<>();
map.put(false, new ArrayList<>());
map.put(true, new ArrayList<>());
return map;
}, (map, x) -> {
boolean partition = p.test(x);
List<Integer> list = map.get(partition);
list.add(x);
}, (map1, map2) -> {
map1.get(false).addAll(map2.get(false));
map1.get(true).addAll(map2.get(true));
});
System.out.println(groups.get(false).size());
System.out.println(groups.get(true).size());
Но его редактирование упоминает, что эта реализация не является поточно-ориентированной. Однако, насколько я вижу, сборщик создает отдельный HashMap<List<Integer>>
для каждого потока в параллельном потоке. Таким образом, каждая карта ограничена одним потоком. Функция разделения также ограничена одним потоком. Функция слияния объединяет результаты нескольких потоков, но, насколько мне известно, структура потоков гарантирует, что слияние будет выполнено потокобезопасным способом. Поэтому мой вопрос: действительно ли это решение не безопасно для потоков?
Кстати: ответ в любом случае дает более элегантное решение (Stream<Integer> stream = intStream.boxed();
et c), но я все еще хотел бы знать.
PS: Я хотел бы добавить этот вопрос в качестве комментария к исходному сообщению, но у меня даже нет репутации добавлять комментарии ...: |