Как найти сумму списка
Короткий ответ
Превратите List<Integer> в поток чисел через mapToInt() и вызовите sum():
void main() {
var numbers = List.of(4, 8, 15, 16, 23, 42);
int sum = numbers.stream().mapToInt(Integer::intValue).sum();
IO.println(sum);
}Результат:
108Сумма поля
Для объектов достаньте нужное поле:
record Item(String name, int quantity, double price) {}
void main() {
var cart = List.of(new Item("Tea", 2, 3.5), new Item("Cake", 1, 12.0));
IO.println(cart.stream().mapToInt(Item::quantity).sum());
IO.println(cart.stream().mapToDouble(i -> i.quantity() * i.price()).sum());
}Результат:
3
19.0Деньги
Сумму BigDecimal считают через reduce() с нулём и сложением:
void main() {
var payments = List.of(new BigDecimal("19.99"), new BigDecimal("5.01"), new BigDecimal("0.10"));
BigDecimal total = payments.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
IO.println(total);
}Результат:
25.10Сумма по группам
summingInt() внутри groupingBy() считает сумму для каждой группы:
record Sale(String city, int amount) {}
void main() {
var sales = List.of(new Sale("Berlin", 100), new Sale("Paris", 50), new Sale("Berlin", 70));
var byCity = sales.stream()
.collect(Collectors.groupingBy(Sale::city, TreeMap::new, Collectors.summingInt(Sale::amount)));
IO.println(byCity);
}Результат:
{Berlin=170, Paris=50}Частая ошибка
Складывать денежные суммы в double. Ошибки округления накапливаются:
void main() {
var prices = List.of(0.1, 0.2, 0.3);
double total = 0;
for (double price : prices) {
total += price;
}
IO.println(total);
}Результат:
0.6000000000000001Функции из этого ответа
- Stream.mapToInt() — Превращает поток объектов в поток чисел `int`.
- IntStream.sum() — Складывает все числа потока.
- Collectors.summingInt() — Сборщик, который суммирует числовое поле элементов.
- BigDecimal — Точное десятичное число — для денег и расчётов, где недопустимы ошибки округления double.