Collectors.toList în Java

Colectori (Collectors) Java 8 (toUnmodifiableList: Java 10)

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.

Sintaxă
static <T> Collector<T, ?, List<T>> toList()
static <T> Collector<T, ?, Set<T>> toSet()
static <T> Collector<T, ?, List<T>> toUnmodifiableList()

Ce face Collectors.toList

Collectors.toList() pune elementele într-o listă, în ordinea din stream. În practică primești un ArrayList pe care îl poți modifica, dar documentația nu promite tipul exact.

Collectors.toSet() pune elementele într-o mulțime: duplicatele dispar, iar ordinea nu este garantată (este un HashSet). Dacă vrei ordine sortată, folosește Collectors.toCollection(TreeSet::new).

Collectors.toUnmodifiableList() creează o listă care nu se poate schimba: add sau set aruncă UnsupportedOperationException. Nu acceptă elemente null. Există și toUnmodifiableSet() și toUnmodifiableMap(...).

Ce returnează

Un Collector care produce un List sau un Set.

Exemple

Exemplul 1: Listă și mulțime din aceleași note

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<Integer> note = List.of(9, 7, 10, 9, 7, 8);

        List<Integer> lista = note.stream().filter(n -> n >= 8).collect(Collectors.toList());
        lista.add(6); // lista se poate modifica
        System.out.println("Listă: " + lista);

        Set<Integer> distincte = note.stream().collect(Collectors.toCollection(TreeSet::new));
        System.out.println("Note distincte, sortate: " + distincte);
        System.out.println("Câte note diferite: " + note.stream().collect(Collectors.toSet()).size());
    }
}

Rezultat

Listă: [9, 10, 9, 8, 6]
Note distincte, sortate: [7, 8, 9, 10]
Câte note diferite: 4

Exemplul 2: toUnmodifiableList: o listă care nu se mai schimbă

Lista de orașe trimisă mai departe nu poate fi modificată din greșeală.

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

public class Main {
    public static void main(String[] args) {
        List<String> orase = List.of("iași", "cluj", "timișoara").stream()
                .map(o -> o.substring(0, 1).toUpperCase() + o.substring(1))
                .collect(Collectors.toUnmodifiableList());
        System.out.println(orase);
        try {
            orase.add("Arad");
        } catch (UnsupportedOperationException e) {
            System.out.println("Lista nu se poate modifica.");
        }
    }
}

Rezultat

[Iași, Cluj, Timișoara]
Lista nu se poate modifica.

Greșeli frecvente

  • Te bazezi pe ordinea din toSet(). Un HashSet nu are ordine stabilă; folosește toCollection(TreeSet::new) sau LinkedHashSet::new.
  • Pui null în stream și folosești toUnmodifiableList(): primești NullPointerException.
  • Crezi că stream.toList() și Collectors.toList() sunt identice. Prima returnează o listă nemodificabilă, a doua una modificabilă.

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.
  • Stream.toList: Adună elementele stream-ului într-o listă care nu se poate modifica, sau într-un tablou cu toArray.
  • Stream.collect: Adună elementele într-un rezultat (listă, set, map, text) folosind un Collector, de obicei din clasa Collectors.
  • Stream.distinct: Elimină duplicatele din stream, păstrând prima apariție a fiecărei valori.