Comparator.comparing în Java

Construiește un comparator care ordonează obiectele după o proprietate: comparing(Elev::nume), comparingInt(Elev::varsta).

Sintaxă
static <T, U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T, ? extends U> cheie)
static <T, U> Comparator<T> comparing(Function<? super T, ? extends U> cheie, Comparator<? super U> c)
static <T> Comparator<T> comparingInt(ToIntFunction<? super T> cheie)
// și comparingLong, comparingDouble

Ce face Comparator.comparing

Comparator.comparing(f) primește o funcție care extrage din fiecare obiect o „cheie” comparabilă (un String, o dată, un număr) și compară obiectele după acea cheie. De obicei funcția este o referință la metodă: Comparator.comparing(Elev::nume).

comparingInt, comparingLong și comparingDouble fac același lucru pentru chei numerice primitive, fără conversia în Integer/Double. Varianta comparing(f, c) compară cheile cu un alt comparator, de exemplu Comparator.reverseOrder() sau String.CASE_INSENSITIVE_ORDER.

Parametri

Parametru Descriere
cheie Funcția care extrage proprietatea după care se ordonează.
c Comparatorul folosit pentru chei (opțional).

Ce returnează

Un Comparator<T> nou.

Exemple

Exemplul 1: Elevi după nume și după vârstă

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class Main {
    record Elev(String nume, int varsta) {}

    public static void main(String[] args) {
        List<Elev> elevi = new ArrayList<>(List.of(
                new Elev("Radu", 17), new Elev("Ana", 18), new Elev("Elena", 16)));
        elevi.sort(Comparator.comparing(Elev::nume));
        System.out.println("După nume: " + elevi);
        elevi.sort(Comparator.comparingInt(Elev::varsta));
        System.out.println("După vârstă: " + elevi);
    }
}

Rezultat

După nume: [Elev[nume=Ana, varsta=18], Elev[nume=Elena, varsta=16], Elev[nume=Radu, varsta=17]]
După vârstă: [Elev[nume=Elena, varsta=16], Elev[nume=Radu, varsta=17], Elev[nume=Ana, varsta=18]]

Exemplul 2: Cheie cu comparator propriu

Cheia este orașul, comparat fără să conteze majusculele; apoi cheia este lungimea, descrescător.

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

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

    public static void main(String[] args) {
        List<Client> clienti = new ArrayList<>(List.of(
                new Client("Ana", "iași"), new Client("Radu", "Arad"), new Client("Elena", "Cluj")));
        clienti.sort(Comparator.comparing(Client::oras, String.CASE_INSENSITIVE_ORDER));
        clienti.forEach(c -> System.out.println(c.oras() + " - " + c.nume()));

        List<String> cuvinte = new ArrayList<>(List.of("cireș", "măr", "portocală", "kiwi"));
        cuvinte.sort(Comparator.comparing(String::length, Comparator.reverseOrder()));
        System.out.println(cuvinte);
    }
}

Rezultat

Arad - Radu
Cluj - Elena
iași - Ana
[portocală, cireș, kiwi, măr]

Greșeli frecvente

  • Folosești comparing(Elev::varsta) pe un câmp int. Merge, dar fiecare valoare devine Integer; comparingInt este mai eficient.
  • Scrii comparing(Elev::nume).reversed() fără tipul explicit într-o lambda (comparing(e -> e.nume()).reversed()). Java nu mai poate deduce tipul lui e și dă eroare; folosește referința la metodă sau Comparator.<Elev, String>comparing(...).

Comenzi înrudite

  • Comparator: Interfața care spune cum se ordonează două obiecte: compare(a, b) returnează un număr negativ, zero sau pozitiv.
  • 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).