it-swarm.com.ru

Как суммировать список целых чисел с потоками Java?

Я хочу подвести список целых чисел. Это работает следующим образом, но синтаксис не выглядит правильным. Может ли код быть оптимизирован?

Map<String, Integer> integers;
integers.values().stream().mapToInt(i -> i).sum();
320
membersound

Это будет работать, но i -> i выполняет некоторую автоматическую распаковку, поэтому "странно". Любое из следующего будет работать и лучше объяснить, что компилятор делает под капотом с вашим оригинальным синтаксисом:

integers.values().stream().mapToInt(i -> i.intValue()).sum();
integers.values().stream().mapToInt(Integer::intValue).sum();
440
Necreaux

Я предлагаю еще 2 варианта:

integers.values().stream().mapToInt(Integer::intValue).sum();
integers.values().stream().collect(Collectors.summingInt(Integer::intValue));

Второй использует Collectors.summingInt() сборщик, есть также summingLong() сборщик, который вы будете использовать с mapToLong.


И третий вариант: Java 8 представляет очень эффективный аккумулятор LongAdder , предназначенный для ускорения суммирования в параллельных потоках и многопоточных средах. Вот пример использования:

LongAdder a = new LongAdder();
map.values().parallelStream().forEach(a::add);
sum = a.intValue();
138
Alex Salauyou

Из документов

Операции сокращения Операция сокращения (также называемая складкой) берет последовательность входных элементов и объединяет их в единый итоговый результат путем многократного применения операции объединения, такой как поиск суммы или максимума набора чисел или накопление элементов в список. Классы потоков имеют несколько форм общих операций редукции, называемых redu () и collect (), а также несколько специализированных форм редукции, таких как sum (), max () или count ().

Конечно, такие операции могут быть легко реализованы в виде простых последовательных циклов, например:

int sum = 0;
for (int x : numbers) {
   sum += x;
}

Тем не менее, есть веские причины, чтобы предпочесть операцию сокращения, а не мутацию, такую ​​как выше. Сокращение не только "более абстрактно" - оно работает с потоком в целом, а не с отдельными элементами, - но правильно сконструированная операция сокращения по своей сути распараллеливается, если функции, используемые для обработки элементов, являются ассоциативными. и без гражданства. Например, учитывая поток чисел, для которого мы хотим найти сумму, мы можем написать:

int sum = numbers.stream().reduce(0, (x,y) -> x+y);

или же:

int sum = numbers.stream().reduce(0, Integer::sum);

Эти операции сокращения могут безопасно выполняться параллельно практически без изменений:

int sum = numbers.parallelStream().reduce(0, Integer::sum);

Итак, для карты вы бы использовали:

integers.values().stream().mapToInt(i -> i).reduce(0, (x,y) -> x+y);

Или же:

integers.values().stream().reduce(0, Integer::sum);
80
J Atkin

Вы можете использовать метод уменьшить:

long sum = result.stream().map(e -> e.getCreditAmount()).reduce(0L, (x, y) -> x + y);

или же

long sum = result.stream().map(e -> e.getCreditAmount()).reduce(0L, Integer::sum);
26
Saeed Zarinfam

Вы можете использовать reduce() для суммирования списка целых чисел.

int sum = integers.values().stream().reduce(0, Integer::sum);
14
Johnson Abraham

Вы можете использовать метод сбора, чтобы добавить список целых чисел.

List<Integer> list = Arrays.asList(2, 4, 5, 6);
int sum = list.stream().collect(Collectors.summingInt(Integer::intValue));
10
Ashish Jha

Это был бы самый короткий способ суммировать массив типа int (для массива longLongStream, для массива doubleDoubleStream и т.д.). Однако не все примитивные целочисленные типы или типы с плавающей запятой имеют реализацию Stream.

IntStream.of(integers).sum();
3
Sachith Dickwella