Ce face Collectors.toMap
Collectors.toMap(cheie, valoare) transformă fiecare element într-o pereche cheie-valoare. De exemplu, din lista de studenți obții map-ul „nume → notă” cu toMap(Student::nume, Student::nota).
Dacă două elemente dau aceeași cheie, varianta cu două argumente aruncă IllegalStateException: Duplicate key. Ca să eviți asta, dai a treia funcție, care combină cele două valori: Integer::sum (aduni), Math::max (păstrezi maximul) sau (a, b) -> a (păstrezi prima).
Map-ul rezultat este un HashMap, fără ordine. Cu al patrulea argument alegi tipul: TreeMap::new pentru chei sortate sau LinkedHashMap::new pentru ordinea din stream.
Parametri
| Parametru | Descriere |
|---|---|
cheie |
Funcția care dă cheia pentru fiecare element. |
valoare |
Funcția care dă valoarea pentru fiecare element. |
combinare |
Opțional: cum se unesc două valori cu aceeași cheie. |
fabricaMap |
Opțional: creează map-ul, de exemplu TreeMap::new. |
Ce returnează
Un Collector care produce un Map<K, U>.
Exemple
Exemplul 1: Nume → notă, cu cheile sortate
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;
public class Main {
record Student(String nume, int nota) {}
public static void main(String[] args) {
List<Student> grupa = List.of(new Student("Radu", 8), new Student("Ana", 10), new Student("Ioana", 9));
Map<String, Integer> note = grupa.stream()
.collect(Collectors.toMap(Student::nume, Student::nota, (a, b) -> a, TreeMap::new));
System.out.println(note);
System.out.println("Nota Anei: " + note.get("Ana"));
}
}
Rezultat
{Ana=10, Ioana=9, Radu=8}
Nota Anei: 10
Exemplul 2: Chei repetate: suma vânzărilor pe oraș
Fără funcția de combinare, al doilea „Iași” ar opri programul cu Duplicate key. Cu Integer::sum, sumele se adună.
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;
public class Main {
record Vanzare(String oras, int lei) {}
public static void main(String[] args) {
List<Vanzare> vanzari = List.of(
new Vanzare("Iași", 120), new Vanzare("Cluj", 300),
new Vanzare("Iași", 80), new Vanzare("Cluj", 50));
try {
vanzari.stream().collect(Collectors.toMap(Vanzare::oras, Vanzare::lei));
} catch (IllegalStateException e) {
System.out.println("Eroare: " + e.getMessage());
}
Map<String, Integer> total = vanzari.stream()
.collect(Collectors.toMap(Vanzare::oras, Vanzare::lei, Integer::sum, TreeMap::new));
System.out.println("Total pe oraș: " + total);
}
}
Rezultat
Eroare: Duplicate key Iași (attempted merging values 120 and 80)
Total pe oraș: {Cluj=350, Iași=200}
Greșeli frecvente
- Nu tratezi cheile repetate. Dacă datele pot avea aceeași cheie de două ori, dă mereu funcția de combinare.
- Funcția de valoare returnează
null:toMaparuncăNullPointerException, chiar dacăHashMapacceptă valorinull. - Folosești
toMapca să numeri sau să grupezi liste de elemente. Pentru asta,groupingByeste mai clar.
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: Clasa cu rețete gata făcute pentru collect: liste, mulțimi, map-uri, texte unite, grupări, numărări și medii.Stream.collect: Adună elementele într-un rezultat (listă, set, map, text) folosind un Collector, de obicei din clasa Collectors.BinaryOperator: O funcție care combină două valori de același tip într-una (T, T → T); folosită de reduce, toMap și Map.merge.