Ce face compareBy
compareBy { it.nota } creează un Comparator: o regulă de comparare după valoarea dată de bloc. Îl dai lui sortedWith, maxWith, sortWith sau unui TreeSet. Cu mai multe blocuri, compareBy({ it.oras }, { it.nume }), compară după primul criteriu, iar la egalitate după al doilea.
Comparatorul obținut se poate extinde: .thenBy { } adaugă un criteriu crescător, .thenByDescending { } unul descrescător, iar .reversed() inversează tot. Pentru un singur criteriu descrescător există compareByDescending { }. Valorile null sunt puse primele.
Parametri
| Parametru | Descriere |
|---|---|
selectors: (T) -> Comparable<*>? |
Unul sau mai multe blocuri care dau valoarea după care se compară. |
Ce returnează
Un Comparator<T>.
Exemple
Exemplul 1: Sortare după mai multe criterii
Studenții sunt ordonați după oraș; în același oraș, după nume.
data class Student(val nume: String, val oras: String, val nota: Int)
fun main() {
val studenti = listOf(
Student("Ion", "Iași", 8),
Student("Ana", "Cluj", 10),
Student("Dan", "Iași", 9),
Student("Bia", "Cluj", 7),
)
studenti.sortedWith(compareBy({ it.oras }, { it.nume }))
.forEach { println("${it.oras}: ${it.nume}") }
}
Rezultat
Cluj: Ana
Cluj: Bia
Iași: Dan
Iași: Ion
Exemplul 2: thenByDescending și maxWith
Produsele sunt ordonate după categorie, apoi de la cel mai scump la cel mai ieftin. Același fel de comparator merge și cu maxWith.
data class Produs(val nume: String, val categorie: String, val pret: Double)
fun main() {
val produse = listOf(
Produs("lapte", "lactate", 7.2),
Produs("pâine", "panificație", 4.5),
Produs("brânză", "lactate", 22.0),
Produs("covrigi", "panificație", 3.0),
)
val ordine = compareBy<Produs> { it.categorie }.thenByDescending { it.pret }
produse.sortedWith(ordine).forEach { println("${it.categorie} – ${it.nume} ${it.pret}") }
println(produse.maxWith(compareBy { it.nume.length }))
}
Rezultat
lactate – brânză 22.0
lactate – lapte 7.2
panificație – pâine 4.5
panificație – covrigi 3.0
Produs(nume=covrigi, categorie=panificație, pret=3.0)
Greșeli frecvente
- Scrii
compareBy { it.nota }.thenBy { it.nume }fără tip și compilatorul nu poate deduce tipul. Scrie tipul explicit:compareBy<Student> { it.nota }. - Folosești
sortedByde două ori la rând, crezând că sortezi după două criterii. A doua sortare o înlocuiește pe prima; folosește un singurcompareBycu mai multe criterii.
Comenzi înrudite
Comparable.compareTo: compareTo compară două obiecte și dă un număr negativ, 0 sau pozitiv; compareValues face la fel și acceptă null.maxOf: Returnează cea mai mare (maxOf) sau cea mai mică (minOf) dintre două sau mai multe valori comparabile.