Collectors.partitioningBy în Java

Împarte elementele în două grupuri, după o condiție: cele care o îndeplinesc (true) și celelalte (false).

Sintaxă
static <T> Collector<T, ?, Map<Boolean, List<T>>> partitioningBy(Predicate<T> conditie)
static <T, D, A> Collector<T, ?, Map<Boolean, D>> partitioningBy(Predicate<T> conditie,
        Collector<T, A, D> downstream)

Ce face Collectors.partitioningBy

partitioningBy(conditie) este o grupare cu doar două chei: true și false. Rezultatul este un Map<Boolean, List<T>>: get(true) dă elementele care respectă condiția, get(false) pe celelalte.

Spre deosebire de groupingBy, ambele chei există mereu, chiar dacă un grup este gol. Ca la groupingBy, poți da un al doilea colector: partitioningBy(n -> n >= 5, Collectors.counting()).

Parametri

Parametru Descriere
conditie Un Predicate care decide în ce parte intră elementul.
downstream Opțional: ce se calculează pentru fiecare parte.

Ce returnează

Un Collector care produce un Map<Boolean, ...> cu cheile false și true.

Exemple

Exemplul 1: Promovați și restanțieri

import java.util.List;
import java.util.Map;
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("Ana", 9), new Student("Radu", 4),
                new Student("Ioana", 7), new Student("Dan", 3));

        Map<Boolean, List<String>> parti = grupa.stream()
                .collect(Collectors.partitioningBy(s -> s.nota() >= 5,
                        Collectors.mapping(Student::nume, Collectors.toList())));

        System.out.println("Promovați: " + parti.get(true));
        System.out.println("Restanțieri: " + parti.get(false));
        System.out.println(parti);
    }
}

Rezultat

Promovați: [Ana, Ioana]
Restanțieri: [Radu, Dan]
{false=[Radu, Dan], true=[Ana, Ioana]}

Exemplul 2: Ambele chei există chiar dacă un grup e gol

Toate numerele sunt pare, dar get(false) dă o listă goală, nu null.

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

public class Main {
    public static void main(String[] args) {
        Map<Boolean, List<Integer>> pare = List.of(2, 4, 6).stream()
                .collect(Collectors.partitioningBy(n -> n % 2 == 0));
        System.out.println("Pare: " + pare.get(true));
        System.out.println("Impare: " + pare.get(false));
    }
}

Rezultat

Pare: [2, 4, 6]
Impare: []

Greșeli frecvente

  • Folosești groupingBy(s -> s.nota() >= 5). Merge, dar dacă un grup este gol, cheia lipsește și get dă null. partitioningBy păstrează ambele chei.
  • Ai nevoie de mai mult de două grupuri. Atunci folosește groupingBy.

Comenzi înrudite

  • Collectors.groupingBy: Împarte elementele în grupuri după o cheie (oraș, grupă, prima literă) și dă un Map cheie → listă sau cheie → rezultat.
  • Predicate: O condiție: primește o valoare și răspunde true sau false prin metoda test; folosită de filter, removeIf, anyMatch.
  • Stream.filter: Păstrează în stream doar elementele care îndeplinesc o condiție.
  • Collectors.mapping: Transformă fiecare element înainte să-l dea altui colector; folosit în groupingBy ca să păstrezi doar un câmp.