Ce face Comparator
Un Comparator<T> este o regulă de ordonare. Metoda lui compare(a, b) returnează un număr negativ dacă a trebuie să vină înaintea lui b, zero dacă sunt „egale” pentru ordonare și pozitiv dacă a vine după b.
Îl dai metodelor care sortează sau caută extreme: lista.sort(c), Collections.sort(lista, c), Arrays.sort(a, c), new TreeSet<>(c), new PriorityQueue<>(c), Collections.max(colectie, c), stream.sorted(c).
Rareori scrii compare de mână. Metodele gata făcute construiesc comparatorul: Comparator.comparing(Elev::nume), comparingInt, naturalOrder, reverseOrder, apoi le combini cu thenComparing și reversed.
Parametri
| Parametru | Descriere |
|---|---|
T |
Tipul obiectelor comparate. |
Ce returnează
compare returnează un int: < 0, 0 sau > 0.
Exemple
Exemplul 1: Un comparator scris ca lambda
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class Main {
public static void main(String[] args) {
Comparator<String> dupaLungime = (a, b) -> Integer.compare(a.length(), b.length());
List<String> orase = new ArrayList<>(List.of("Constanța", "Iași", "Brașov", "Arad"));
orase.sort(dupaLungime);
System.out.println(orase);
System.out.println(dupaLungime.compare("Iași", "Brașov"));
System.out.println(dupaLungime.compare("Iași", "Arad"));
}
}
Rezultat
[Iași, Arad, Brașov, Constanța]
-1
0
Exemplul 2: Același comparator în mai multe locuri
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
public class Main {
record Produs(String nume, double pret) {}
public static void main(String[] args) {
Comparator<Produs> dupaPret = Comparator.comparingDouble(Produs::pret);
List<Produs> produse = List.of(new Produs("cafea", 24.5), new Produs("ceai", 9.9), new Produs("lapte", 7.2));
System.out.println("Cel mai scump: " + Collections.max(produse, dupaPret).nume());
TreeSet<Produs> sortate = new TreeSet<>(dupaPret);
sortate.addAll(produse);
sortate.forEach(p -> System.out.println(p.nume() + " " + p.pret()));
}
}
Rezultat
Cel mai scump: cafea
lapte 7.2
ceai 9.9
cafea 24.5
Greșeli frecvente
- Scrii
(a, b) -> a.varsta() - b.varsta(). Pentru numere mari scăderea poate depășiintși dă semnul greșit; foloseșteInteger.comparesauComparator.comparingInt. - Comparatorul returnează 0 pentru obiecte diferite într-un
TreeSet/TreeMap. Sunt considerate același element și unul dispare; adaugă criterii cuthenComparing. - Confunzi
Comparator(regulă separată) cuComparable(ordinea „naturală” scrisă în clasă princompareTo).
Comenzi înrudite
Comparator.comparing: Construiește un comparator care ordonează obiectele după o proprietate: comparing(Elev::nume), comparingInt(Elev::varsta).Comparator.thenComparing: thenComparing adaugă un criteriu secundar pentru elementele egale după primul; reversed() inversează un comparator.Comparator.naturalOrder: naturalOrder() compară obiectele după ordinea lor naturală (crescător); reverseOrder() după ordinea inversă (descrescător).List.sort: Sortează lista pe loc după comparatorul dat; cu null sortează în ordinea naturală (numere crescător, texte alfabetic).Collections.sort: Sortează o listă pe loc: crescător după ordinea naturală sau după un Comparator dat. Echivalent cu lista.sort(…).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”.