В этом коротком руководстве мы рассмотрим различные способы вычисления суммы целых чисел с помощью Stream API.
Для простоты в наших примерах мы будем использовать Integer числа, однако можно применить те же методы и к типам Long и Double.
Использование Stream.reduce()
Stream.reduce() – это терминальная операция, которая выполняет сокращение элементов в стриме.
Операция применяет бинарный оператор (аккумулятор) к каждому элементу в стриме, где первый операнд является возвращаемым значением предыдущего элемента, а второй – текущим элементом стрима.
В первом примере функция-аккумулятор представляет собой лямбда-выражение, которое складывает два целых значения и возвращает также целое значение:
List<Integer> ints = Arrays.asList(1, 2, 3, 4);
Integer sum = ints.stream()
.reduce(0, (a, b) -> a + b);
Таким же образом мы можем использовать статический Java-метод Integer::sum:
List<Integer> ints = Arrays.asList(1, 2, 3, 4);
Integer sum = ints.stream()
.reduce(0, Integer::sum);
Или мы можем определить и использовать наш пользовательский метод:
public class MathUtils {
public static int add(int a, int b) {
return a + b;
}
}
//...
List<Integer> ints = Arrays.asList(1, 2, 3, 4);
Integer sum = ints.stream()
.reduce(0, MathUtils::add);
Использование Stream.collect()
Второй способ вычисления суммы списка целых чисел заключается в использовании терминальной операции collect():
List<Integer> ints = Arrays.asList(1, 2, 3, 4);
Integer sum = ints.stream()
.collect(Collectors.summingInt(Integer::intValue));
Аналогично, класс Collectors предоставляет методы summingLong() и summingDouble() для вычисления сумм коллекций типов Long и Double соответственно.
Использование IntStream.sum()
Stream API предоставляет нам промежуточную операцию mapToInt(), которая преобразует наш стрим в объект IntStream.
Этот метод принимает mapper в качестве параметра, который он использует для выполнения преобразования, затем мы можем вызвать метод sum() для вычисления суммы элементов стрима.
Давайте посмотрим на короткий пример того, как мы можем его использовать:
List<Integer> ints = Arrays.asList(1, 2, 3, 4);
Integer sum = ints.stream()
.mapToInt(Integer::intValue)
.sum();
Таким же образом мы можем использовать методы mapToLong() и mapToDouble() для вычисления сумм коллекций типов Long и Double соответственно.
Использование Stream#sum с map
Чтобы вычислить сумму значений структуры данных Map<Object, Integer>, сначала мы создадим стрим из значений этого map. Далее применим один из методов, которые мы использовали ранее. Например, IntStream.sum():
Integer sum = map.values()
.stream()
.mapToInt(Integer::valueOf)
.sum();
Использование Stream#sum с объектами
Давайте представим, что у нас есть список объектов и мы хотим вычислить сумму всех значений выбранного поля этих объектов.
Например:
public class Item {
private int id;
private Integer price;
public Item(int id, Integer price) {
this.id = id;
this.price = price;
}
// стандартные геттеры и сеттеры
}
Далее давайте представим, что мы хотим рассчитать итоговую цену всех товаров из следующего списка:
Item item1 = new Item(1, 5);
Item item2 = new Item(2, 10);
Item item3 = new Item(3, 15);
Item item4 = new Item(4, 20);
List<Item> items = Arrays.asList(item1, item2, item3, item4);
Чтобы вычислить сумму, используя методы, показанные в предыдущих примерах, нам нужно вызвать метод map() для преобразования нашего стрима в стрим целых чисел.
Можно использовать Stream.reduce(), Stream.collect() и IntStream.sum() для вычисления суммы:
Можно использовать Stream.reduce(), Stream.collect() и IntStream.sum() для вычисления суммы:
Integer sum = items.stream()
.map(x -> x.getPrice())
.reduce(0, ArithmeticUtils::add);
sum = items.stream()
.map(x -> x.getPrice())
.reduce(0, Integer::sum);
sum = items.stream()
.map(item -> item.getPrice())
.reduce(0, (a, b) -> a + b);
sum = items.stream()
.map(x -> x.getPrice())
.collect(Collectors.summingInt(Integer::intValue));
sum = items.stream()
.mapToInt(x -> x.getPrice())
.sum();
Заключение
В этой статье мы рассмотрели несколько методов вычисления суммы списка целых чисел с помощью Stream API. Мы также использовали эти методы для вычисления суммы значений выбранного поля списка объектов и суммы значений map.