Потоки не подходят для такого рода задач, поскольку в них присутствует состояние (накопленная частичная сумма). Вместо этого вы можете использовать Arrays.parallelPrefix
:
Integer[] arr = list1.toArray(Integer[]::new);
Arrays.parallelPrefix(arr, Integer::sum);
List<Integer> list2 = Arrays.asList(arr);
Сначала копируется list1
в массив с помощью Collection.toArray
, который доступен с JDK 11. Если вы еще не используете Java 11, вы можете заменить первую строку на традиционную toArray
Звоните:
Integer[] arr = list1.toArray(new Integer[0]);
Это решение не использует потоки, но оно декларативное , потому что Arrays.parallelPrefix
получает накопительную операцию в качестве аргумента (Integer::sum
в данном случае).
Сложность по времени составляет O(N)
, хотя при настройке инфраструктуры, необходимой для параллельной обработки, могут возникнуть некоторые незначительные постоянные затраты. Однако согласно документам:
Параллельное вычисление префикса обычно более эффективно, чем последовательные циклы для больших массивов
Так что, похоже, стоит попробовать этот подход.
Также стоит отметить, что этот подход работает, потому что Integer::sum
является ассоциативной операцией . Это требование.