Iterable.sortedWith în Kotlin

Sortează după un Comparator: mai multe criterii cu compareBy/thenBy sau ordine românească cu Collator.

Sintaxă
fun <T> Iterable<T>.sortedWith(comparator: Comparator<in T>): List<T>

Ce face Iterable.sortedWith

sortedWith primește un Comparator, adică o regulă care spune care din două elemente vine primul. Este varianta cea mai flexibilă de sortare.

Comparatoare obișnuite: compareBy({ criteriu1 }, { criteriu2 }) sau compareBy<T> { ... }.thenByDescending { ... } pentru mai multe criterii, naturalOrder(), reverseOrder(), nullsLast(), și pe JVM java.text.Collator pentru ordinea alfabetică a unei limbi (cu ă, â, î, ș, ț la locul lor).

Parametri

Parametru Descriere
comparator Regula de comparare a două elemente.

Ce returnează

O List<T> nouă, sortată după comparator.

Exemple

Exemplul 1: Două criterii: clasa, apoi media descrescător

Elevii sunt grupați după clasă; în aceeași clasă, cel cu media mai mare vine primul.

data class Elev(val nume: String, val clasa: String, val medie: Double)

fun main() {
    val elevi = listOf(
        Elev("Ana", "9B", 9.1), Elev("Ion", "9A", 8.4),
        Elev("Maria", "9A", 9.7), Elev("Radu", "9B", 9.6),
    )
    val ordonati = elevi.sortedWith(compareBy<Elev> { it.clasa }.thenByDescending { it.medie })
    ordonati.forEach { println("${it.clasa} ${it.nume} ${it.medie}") }
}

Rezultat

9A Maria 9.7
9A Ion 8.4
9B Radu 9.6
9B Ana 9.1

Exemplul 2: Ordine alfabetică românească

sorted() pune „Ștefan” și „Țiriac” după „Zamfir”. Un Collator pentru limba română le pune la locul lor din dicționar.

import java.text.Collator
import java.util.Locale

fun main() {
    val nume = listOf("Zamfir", "Ștefan", "Sorin", "Țiriac", "Toma", "Andrei")
    println(nume.sorted())
    val ro = Collator.getInstance(Locale.forLanguageTag("ro"))
    println(nume.sortedWith(ro))
}

Rezultat

[Andrei, Sorin, Toma, Zamfir, Ștefan, Țiriac]
[Andrei, Sorin, Ștefan, Țiriac, Toma, Zamfir]

Exemplul 3: Valori lipsă la final

Unele produse nu au preț (null). nullsLast le trimite la sfârșit, iar restul se sortează crescător.

fun main() {
    val preturi = listOf(25, null, 9, 40, null, 12)
    println(preturi.sortedWith(nullsLast(naturalOrder())))
}

Rezultat

[9, 12, 25, 40, null, null]

Greșeli frecvente

  • Scrii compareBy { it.clasa }.thenBy { ... } fără tipul elementului: uneori compilatorul nu îl poate deduce. Scrie compareBy<Elev> { ... }.
  • Construiești un Collator cu Locale("ro"): constructorul este depreciat în Java recent. Folosește Locale.forLanguageTag("ro").

Comenzi înrudite

  • Iterable.sorted: Întoarce o listă nouă cu elementele în ordine crescătoare (sorted) sau descrescătoare (sortedDescending).
  • Iterable.sortedBy: Sortează elementele după valoarea calculată de o funcție, de exemplu elevii după medie sau orașele după populație.
  • compareBy: Creează un Comparator care compară obiectele după una sau mai multe proprietăți, în ordine; se folosește cu sortedWith.
  • Comparable.compareTo: compareTo compară două obiecte și dă un număr negativ, 0 sau pozitiv; compareValues face la fel și acceptă null.
  • MutableList.sort: Sortează chiar lista modificabilă (pe loc), crescător, descrescător sau după un câmp; nu întoarce nimic.