Фильтрация коллекций
Фильтрация — одна из самых распространённых задач при обработке коллекций. В Kotlin условия фильтрации задаются предикатами — лямбда-функциями, которые принимают элемент коллекции и возвращают логическое значение: true означает, что заданный элемент соответствует предикату, false означает обратное.
Стандартная библиотека содержит набор функций-расширений, позволяющих отфильтровать коллекции одним вызовом. Эти функции не изменяют исходную коллекцию, поэтому доступны как для изменяемых, так и для коллекций только для чтения. Чтобы использовать результат фильтрации, присвойте его переменной или объедините вызовы функций в цепочку после фильтрации.
Фильтрация по предикату
Основная функция фильтрации — filter(). При вызове с предикатом filter() возвращает элементы коллекции, которые ему соответствуют. Для List и Set результирующая коллекция имеет тип List, а для Map — также тип Map.
fun main() {
//sampleStart
val numbers = listOf("one", "two", "three", "four")
val longerThan3 = numbers.filter { it.length > 3 }
println(longerThan3)
val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
val filteredMap = numbersMap.filter { (key, value) -> key.endsWith("1") && value > 10}
println(filteredMap)
//sampleEnd
}
Предикаты в filter() могут проверять только значения элементов. Если при фильтрации нужно использовать позиции элементов, воспользуйтесь функцией filterIndexed(). Она принимает предикат с двумя аргументами: индексом и значением элемента.
Для фильтрации коллекций по отрицательным условиям используйте функцию filterNot(). Она возвращает список элементов, для которых предикат возвращает false.
fun main() {
//sampleStart
val numbers = listOf("one", "two", "three", "four")
val filteredIdx = numbers.filterIndexed { index, s -> (index != 0) && (s.length < 5) }
val filteredNot = numbers.filterNot { it.length <= 3 }
println(filteredIdx)
println(filteredNot)
//sampleEnd
}
Существуют также функции, которые сужают тип элементов, фильтруя элементы заданного типа:
-
filterIsInstance()возвращает элементы коллекции заданного типа. При вызове дляList<Any>функцияfilterIsInstance<T>()возвращаетList<T>, что позволяет вызывать для её элементов функции типаT.fun main() { //sampleStart val numbers = listOf(null, 1, "two", 3.0, "four") println("All String elements in upper case:") numbers.filterIsInstance<String>().forEach { println(it.uppercase()) } //sampleEnd } -
filterNotNull()возвращает все ненулевые элементы. При вызове дляList<T?>функцияfilterNotNull()возвращаетList<T: Any>, что позволяет обращаться с элементами как с ненулевыми объектами.fun main() { //sampleStart val numbers = listOf(null, "one", "two", null) numbers.filterNotNull().forEach { println(it.length) // length is unavailable for nullable Strings } //sampleEnd }
Разбиение на части
Ещё одна функция фильтрации — partition() — фильтрует коллекцию по предикату и сохраняет элементы, которые ему не соответствуют, в отдельный список. В результате возвращается Pair из List: первый список содержит элементы, соответствующие предикату, а второй — все остальные элементы исходной коллекции.
fun main() {
//sampleStart
val numbers = listOf("one", "two", "three", "four")
val (match, rest) = numbers.partition { it.length > 3 }
println(match)
println(rest)
//sampleEnd
}
Проверка предикатов
Наконец, существуют функции, которые просто проверяют предикат для элементов коллекции:
any()возвращаетtrue, если хотя бы один элемент соответствует заданному предикату.none()возвращаетtrue, если ни один из элементов не соответствует заданному предикату.all()возвращаетtrue, если все элементы соответствуют заданному предикату. Обратите внимание:all()возвращаетtrueпри вызове с любым корректным предикатом для пустой коллекции. Такое поведение в логике называется вакуумной истинностью.
fun main() {
//sampleStart
val numbers = listOf("one", "two", "three", "four")
println(numbers.any { it.endsWith("e") })
println(numbers.none { it.endsWith("a") })
println(numbers.all { it.endsWith("e") })
println(emptyList<Int>().all { it > 5 }) // vacuous truth
//sampleEnd
}
any() и none() также можно использовать без предиката: в этом случае они просто проверяют, пуста ли коллекция. any() возвращает true, если коллекция содержит элементы, и false, если не содержит; none() действует наоборот.
fun main() {
//sampleStart
val numbers = listOf("one", "two", "three", "four")
val empty = emptyList<String>()
println(numbers.any())
println(empty.any())
println(numbers.none())
println(empty.none())
//sampleEnd
}
© 2010–2026 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/collection-filtering.html