How to sum a list
Short answer
Turn a List<Integer> into a number stream with mapToInt() and call sum():
void main() {
var numbers = List.of(4, 8, 15, 16, 23, 42);
int sum = numbers.stream().mapToInt(Integer::intValue).sum();
IO.println(sum);
}Output:
108Summing a field
For objects, extract the field you need:
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());
}Output:
3
19.0Money
A sum of BigDecimal values is calculated with reduce(), zero and addition:
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);
}Output:
25.10Sums by group
summingInt() inside groupingBy() calculates a sum for each group:
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);
}Output:
{Berlin=170, Paris=50}Common mistake
Adding money amounts as double. Rounding errors accumulate:
void main() {
var prices = List.of(0.1, 0.2, 0.3);
double total = 0;
for (double price : prices) {
total += price;
}
IO.println(total);
}Output:
0.6000000000000001Functions used in this recipe
- Stream.mapToInt() — Turns a stream of objects into a stream of `int` numbers.
- IntStream.sum() — Adds up all numbers of a stream.
- Collectors.summingInt() — A collector that sums a numeric field of the elements.
- BigDecimal — An exact decimal number — for money and calculations where double rounding errors are unacceptable.