Как сортировать список по определённому критерию?
В Kotlin сортировка списков может выполняться разными способами в зависимости от типа коллекции (изменяемая или нет) и от критерия, по которому происходит сортировка. Kotlin предоставляет удобные функции для сортировки как по возрастанию, так и по убыванию, а также по произвольным критериям — через lambda-выражения. Эти функции можно применять к спискам простых типов (числа, строки) или спискам объектов (data class и т.д.).
Сортировка по возрастанию
Если у вас есть список чисел или строк, вы можете отсортировать его по умолчанию в порядке возрастания с помощью:
val numbers = listOf(5, 2, 8, 1)
val sorted = numbers.sorted() // \[1, 2, 5, 8\]
-
sorted() возвращает новый неизменяемый список.
-
numbers остаётся неизменным.
Для строк:
val names = listOf("Charlie", "Alice", "Bob")
val sorted = names.sorted() // \[Alice, Bob, Charlie\]
Сортировка по убыванию
Используется sortedDescending():
val numbers = listOf(5, 2, 8, 1)
val sorted = numbers.sortedDescending() // \[8, 5, 2, 1\]
Сортировка по определённому критерию: sortedBy
Если нужно отсортировать список по ключу, извлекаемому из элемента, используйте sortedBy:
data class User(val name: String, val age: Int)
val users = listOf(
User("Alice", 32),
User("Bob", 25),
User("Charlie", 40)
)
val sortedByAge = users.sortedBy { it.age }
// \[Bob(25), Alice(32), Charlie(40)\]
- Возвращается новый список, упорядоченный по значению, возвращаемому из lambda (в данном случае — it.age).
Сортировка по убыванию критерия: sortedByDescending
val sortedByAgeDesc = users.sortedByDescending { it.age }
// \[Charlie(40), Alice(32), Bob(25)\]
Множественная сортировка: thenBy, thenByDescending
Если нужно сортировать сначала по одному критерию, потом — по второму (например, по фамилии, а потом по имени), используется комбинирование:
data class Person(val firstName: String, val lastName: String)
val people = listOf(
Person("John", "Smith"),
Person("Alice", "Brown"),
Person("Bob", "Smith")
)
val sorted = people
.sortedWith(compareBy({ it.lastName }, { it.firstName }))
// \[Alice Brown, Bob Smith, John Smith\]
Или по убыванию:
val sortedDesc = people
.sortedWith(compareByDescending<Person> { it.lastName }
.thenByDescending { it.firstName })
sortedWith и Comparator
Вы можете использовать Comparator, если хотите более гибкий контроль над логикой сортировки:
val comparator = Comparator<User> { a, b ->
a.age.compareTo(b.age)
}
val sorted = users.sortedWith(comparator)
Можно инлайн:
val sorted = users.sortedWith(compareBy { it.age })
Сортировка изменяемого списка "на месте": sort, sortBy
Если у вас mutableList, вы можете сортировать на месте, без создания нового списка:
val list = mutableListOf(5, 2, 1, 4)
list.sort() // Сортирует по возрастанию
list.sortDescending() // По убыванию
list.sortBy { it % 3 } // По остатку от деления на 3
Для списков объектов:
val users = mutableListOf(
User("Alice", 32),
User("Bob", 25),
User("Charlie", 40)
)
users.sortBy { it.age } // изменяет сам список
Сортировка с null-значениями
Если в поле может быть null, можно использовать:
val names = listOf("Tom", null, "Anna")
val sorted = names.sortedWith(compareBy(nullsLast()) { it })
// \[Anna, Tom, null\]
val sorted2 = names.sortedWith(compareBy(nullsFirst()) { it })
// \[null, Anna, Tom\]
Особые кейсы: сортировка по длине строки
val words = listOf("apple", "banana", "kiwi", "pear")
val sortedByLength = words.sortedBy { it.length }
// \[kiwi, pear, apple, banana\]
Сортировка чисел по модулю
val nums = listOf(-10, 2, -3, 7, -1)
val sortedByAbs = nums.sortedBy { kotlin.math.abs(it) }
// \[-1, 2, -3, 7, -10\]
Сортировка по нескольким полям с null'ами и убыванием
data class Employee(val name: String?, val salary: Int)
val list = listOf(
Employee("John", 3000),
Employee(null, 2500),
Employee("Alice", 4000)
)
val sorted = list.sortedWith(
compareBy(nullsLast()) { it.name }
.thenByDescending { it.salary }
)
Интересный приём — сортировка по булевому условию
val items = listOf("apple", "banana", "kiwi", "avocado")
val sorted = items.sortedBy { !it.startsWith("a") }
// элементы, начинающиеся с 'a', окажутся в начале
// \[apple, avocado, banana, kiwi\]
Сортировка Map по ключу или значению
val map = mapOf("b" to 2, "a" to 1, "c" to 3)
val sortedByKey = map.toSortedMap()
// {a=1, b=2, c=3}
val sortedByValue = map.entries
.sortedBy { it.value }
// \[a=1, b=2, c=3\]
val resultMap = sortedByValue.associate { it.toPair() }
// {a=1, b=2, c=3}
Сортировка в Data Binding или Jetpack Compose
В UI-приложениях сортировка применяется внутри ViewModel или при подготовке списка:
val displayedItems = \_items.value.sortedBy { it.title }
Все функции сортировки возвращают новую коллекцию, если вы используете List, и изменяют оригинальную, если работаете с MutableList и функциями sort, sortBy, sortWith. Сортировка в Kotlin максимально лаконична, мощна и безопасна — особенно в сочетании с лямбдами, compareBy, thenBy, nullsFirst, nullsLast, и Comparator.