Stream.collect în Java

Adună elementele într-un rezultat (listă, set, map, text) folosind un Collector, de obicei din clasa Collectors.

Sintaxă
<R, A> R collect(Collector<? super T, A, R> colector)
<R> R collect(Supplier<R> creare, BiConsumer<R, ? super T> adauga, BiConsumer<R, R> combina)

Ce face Stream.collect

collect este operația finală cea mai flexibilă. Îi dai un „colector” care spune cum se adună elementele: Collectors.toSet() într-un set, Collectors.joining(", ") într-un text, Collectors.groupingBy(...) într-un map pe grupe, Collectors.toMap(...) într-un map cheie-valoare.

Varianta cu trei argumente îți permite să construiești singur rezultatul: cum se creează recipientul (StringBuilder::new), cum se adaugă un element și cum se combină două recipiente (folosit la stream-uri paralele).

Parametri

Parametru Descriere
colector Rețeta de adunare, de obicei din Collectors.
creare, adauga, combina Pentru varianta lungă: crearea recipientului, adăugarea unui element și unirea a două recipiente.

Ce returnează

Rezultatul produs de colector (o listă, un set, un map, un text, un număr).

Exemple

Exemplul 1: Același stream, colectori diferiți

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

public class Main {
    public static void main(String[] args) {
        List<String> orase = List.of("Iași", "Cluj", "Iași", "Arad");

        Set<String> unice = orase.stream().collect(Collectors.toCollection(TreeSet::new));
        String text = orase.stream().collect(Collectors.joining(", ", "[", "]"));
        long cate = orase.stream().collect(Collectors.counting());

        System.out.println(unice);
        System.out.println(text);
        System.out.println(cate);
    }
}

Rezultat

[Arad, Cluj, Iași]
[Iași, Cluj, Iași, Arad]
4

Exemplul 2: Gruparea studenților pe orașe

TreeMap::new ține cheile sortate, deci rezultatul apare mereu în aceeași ordine.

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

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

    public static void main(String[] args) {
        List<Student> studenti = List.of(
                new Student("Ana", "Iași"), new Student("Radu", "Cluj"),
                new Student("Ioana", "Iași"), new Student("Dan", "Arad"));

        Map<String, List<String>> peOrase = studenti.stream()
                .collect(Collectors.groupingBy(Student::oras, TreeMap::new,
                        Collectors.mapping(Student::nume, Collectors.toList())));
        System.out.println(peOrase);
    }
}

Rezultat

{Arad=[Dan], Cluj=[Radu], Iași=[Ana, Ioana]}

Exemplul 3: Varianta cu trei funcții

import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        StringBuilder sb = Stream.of("I", "a", "ș", "i")
                .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append);
        System.out.println(sb);
    }
}

Rezultat

Iași

Greșeli frecvente

  • Scrii collect(Collectors.toList()) când ai Java 16+. toList() este mai scurt (dar lista lui nu se poate modifica).
  • Colectezi cu groupingBy sau toSet și afișezi rezultatul așteptând o ordine anume. HashMap și HashSet nu au ordine garantată; folosește TreeMap::new/TreeSet::new.

Comenzi înrudite

  • Collectors: Clasa cu rețete gata făcute pentru collect: liste, mulțimi, map-uri, texte unite, grupări, numărări și medii.
  • Collectors.toList: Adună elementele stream-ului într-o listă (toList), într-o mulțime fără duplicate (toSet) sau într-o listă ce nu se poate modifica.
  • Collectors.groupingBy: Împarte elementele în grupuri după o cheie (oraș, grupă, prima literă) și dă un Map cheie → listă sau cheie → rezultat.
  • Collectors.joining: Unește textele din stream într-un singur String, cu un separator și, opțional, un început și un sfârșit.
  • Collectors.toMap: Construiește un Map din stream: o funcție dă cheia, alta valoarea; o a treia spune ce faci când cheia se repetă.
  • Stream.toList: Adună elementele stream-ului într-o listă care nu se poate modifica, sau într-un tablou cu toArray.