Похоже, filter
лучше подходит для решения этой проблемы.Однако, если вы хотите использовать сокращение, и особенно при его параллельном использовании, вы не должны изменять объекты аккумулятора (списки в вашем случае).
Из Oracle учебник по сокращению :
функция аккумулятора также возвращает новое значение каждый раз , она обрабатывает элемент
Когда я запускаю ваш кодЯ получил две распечатки списка, содержащие null
, а затем ArrayIndexOutOfBoundsException
.Вероятная причина этого заключается в том, что два потока пытались добавить элементы в один и тот же список одновременно.Исключение произошло после того, как список был увеличен, но до добавления элемента, следовательно, слот null
(то есть пустой).
ArrayList<String> strings2 =
s1.parallel()
.reduce(new ArrayList<String>(),
(list, el) -> {
if (el.contains("a")) {
ArrayList<String> added = new ArrayList<>(list);
added.add(el);
return added;
}
return list;
},
(list1, list2) -> {
ArrayList<String> merged = new ArrayList<>(list1);
merged.addAll(list2);
return merged;
});
Вместо добавления в список, вы должны сделать копиюдобавьте к этой копии и верните копию.Таким образом, каждый поток может работать с разными частями ввода, не мешая другим.
Кроме того, вы не можете просто выбросить часть результата в сумматоре, иначе у вас получатся неполные результаты.Вы должны объединить списки, а не просто вернуть один из них.