Ce face Comparator.thenComparing
c1.thenComparing(c2) returnează un comparator care folosește întâi c1, iar doar dacă c1 spune că elementele sunt egale (0), folosește c2. Așa sortezi „după clasă, apoi după nume, apoi după vârstă”. Există și variantele thenComparing(cheie), thenComparingInt, thenComparingDouble.
c.reversed() returnează comparatorul invers. Atenție: reversed() inversează tot lanțul construit până în acel punct. Pentru a inversa doar un criteriu, pune-l separat: comparing(A).thenComparing(comparing(B).reversed()) sau thenComparing(B, Comparator.reverseOrder()).
Parametri
| Parametru | Descriere |
|---|---|
other |
Comparatorul secundar. |
cheie |
Funcția care extrage proprietatea secundară. |
Ce returnează
Un comparator nou, compus.
Exemple
Exemplul 1: Clasament: media descrescător, apoi numele
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class Main {
record Elev(String nume, double medie) {}
public static void main(String[] args) {
List<Elev> elevi = new ArrayList<>(List.of(
new Elev("Radu", 9.50), new Elev("Ana", 9.80), new Elev("Elena", 9.50), new Elev("Bogdan", 8.90)));
elevi.sort(Comparator.comparingDouble(Elev::medie).reversed().thenComparing(Elev::nume));
int loc = 1;
for (Elev e : elevi) {
System.out.println(loc++ + ". " + e.nume() + " " + e.medie());
}
}
}
Rezultat
1. Ana 9.8
2. Elena 9.5
3. Radu 9.5
4. Bogdan 8.9
Exemplul 2: Unde pui reversed() contează
În primul caz, reversed() inversează ambele criterii; în al doilea, doar orașul crescător și vârsta descrescător.
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class Main {
record Persoana(String oras, int varsta) {}
public static void main(String[] args) {
List<Persoana> p = new ArrayList<>(List.of(
new Persoana("Iași", 30), new Persoana("Arad", 25), new Persoana("Iași", 22), new Persoana("Arad", 41)));
p.sort(Comparator.comparing(Persoana::oras).thenComparingInt(Persoana::varsta).reversed());
System.out.println(p);
p.sort(Comparator.comparing(Persoana::oras).thenComparing(Persoana::varsta, Comparator.reverseOrder()));
System.out.println(p);
}
}
Rezultat
[Persoana[oras=Iași, varsta=30], Persoana[oras=Iași, varsta=22], Persoana[oras=Arad, varsta=41], Persoana[oras=Arad, varsta=25]]
[Persoana[oras=Arad, varsta=41], Persoana[oras=Arad, varsta=25], Persoana[oras=Iași, varsta=30], Persoana[oras=Iași, varsta=22]]
Greșeli frecvente
- Pui
reversed()la final crezând că inversează doar ultimul criteriu. Inversează tot lanțul. - Sortezi de două ori (întâi după nume, apoi după medie) în loc de
thenComparing. Merge doar pentru că sortarea e stabilă și doar în ordinea inversă a criteriilor;thenComparinge mai clar.
Comenzi înrudite
Comparator: Interfața care spune cum se ordonează două obiecte: compare(a, b) returnează un număr negativ, zero sau pozitiv.Comparator.comparing: Construiește un comparator care ordonează obiectele după o proprietate: comparing(Elev::nume), comparingInt(Elev::varsta).Comparator.naturalOrder: naturalOrder() compară obiectele după ordinea lor naturală (crescător); reverseOrder() după ordinea inversă (descrescător).TreeSet: Mulțime care ține elementele mereu sortate (crescător sau după un Comparator) și oferă căutări de tip „cel mai mic”, „cel mai apropiat”.List.sort: Sortează lista pe loc după comparatorul dat; cu null sortează în ordinea naturală (numere crescător, texte alfabetic).