Collectors.summingInt în Java

Adună un câmp numeric al elementelor (summingInt) sau îi calculează media (averagingDouble), de obicei pe grupuri.

Sintaxă
static <T> Collector<T, ?, Integer> summingInt(ToIntFunction<T> f)
static <T> Collector<T, ?, Double> averagingDouble(ToDoubleFunction<T> f)

Ce face Collectors.summingInt

summingInt(f) aplică funcția f fiecărui element și adună rezultatele într-un Integer. Există și summingLong și summingDouble.

averagingDouble(f) calculează media valorilor date de f și returnează un Double. Pentru un grup gol media este 0.0. Există și averagingInt și averagingLong, care tot Double returnează.

Ambele sunt utile mai ales ca downstream în groupingBy: „totalul vânzărilor pe oraș” sau „media notelor pe grupă”. Pentru un singur total, mapToInt(...).sum() este mai direct.

Parametri

Parametru Descriere
f Funcția care scoate numărul din fiecare element, de exemplu Produs::pret.

Ce returnează

Un Collector care produce suma (Integer) sau media (Double).

Exemple

Exemplul 1: Total și medie pe categorie de produse

import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;

public class Main {
    record Produs(String nume, String categorie, int pret) {}

    public static void main(String[] args) {
        List<Produs> cos = List.of(
                new Produs("pâine", "alimente", 5), new Produs("lapte", "alimente", 8),
                new Produs("caiet", "papetărie", 12), new Produs("pix", "papetărie", 3),
                new Produs("brânză", "alimente", 27));

        Map<String, Integer> total = cos.stream()
                .collect(Collectors.groupingBy(Produs::categorie, TreeMap::new, Collectors.summingInt(Produs::pret)));
        Map<String, Double> medie = cos.stream()
                .collect(Collectors.groupingBy(Produs::categorie, TreeMap::new, Collectors.averagingDouble(Produs::pret)));

        System.out.println("Total (lei): " + total);
        System.out.println("Preț mediu (lei): " + medie);
    }
}

Rezultat

Total (lei): {alimente=40, papetărie=15}
Preț mediu (lei): {alimente=13.333333333333334, papetărie=7.5}

Exemplul 2: Media generală a unei grupe

Fără grupare, averagingDouble dă media tuturor. Pe o listă goală rezultatul este 0.0, nu o eroare.

import java.util.List;
import java.util.stream.Collectors;

public class Main {
    record Student(String nume, double nota) {}

    public static void main(String[] args) {
        List<Student> grupa = List.of(new Student("Ana", 9.5), new Student("Radu", 7.0), new Student("Ioana", 8.5));
        double media = grupa.stream().collect(Collectors.averagingDouble(Student::nota));
        System.out.printf("Media grupei: %.2f%n", media);

        double goala = List.<Student>of().stream().collect(Collectors.averagingDouble(Student::nota));
        System.out.println("Media unei grupe goale: " + goala);
    }
}

Rezultat

Media grupei: 8.33
Media unei grupe goale: 0.0

Greșeli frecvente

  • Aștepți o eroare sau NaN pentru un grup gol. averagingDouble dă 0.0, ceea ce poate ascunde lipsa datelor; verifică separat dacă există elemente.
  • Sumezi valori mari cu summingInt și ieși din domeniul lui int fără niciun avertisment. Folosește summingLong.

Comenzi înrudite

  • Collectors.groupingBy: Împarte elementele în grupuri după o cheie (oraș, grupă, prima literă) și dă un Map cheie → listă sau cheie → rezultat.
  • Collectors.counting: Numără elementele; folosit mai ales în groupingBy, pentru „câte elemente are fiecare grup”.
  • IntStream.sum: sum adună numerele din IntStream; average dă media lor ca OptionalDouble (gol dacă nu există numere).
  • IntStream.summaryStatistics: Calculează într-o singură trecere numărul, suma, minimul, maximul și media numerelor din IntStream.