过滤
标准库包含了一组让你能够通过单个调用就可以过滤集合的扩展函数。这些函数不会改变原始集合,因此它们。为了操作过滤结果,应该在过滤后将其赋值给变量或链接其他函数。
基本的过滤函数是 filter()
。当使用一个谓词来调用时,filter()
返回与其匹配的集合元素。对于 List
和 Set
,过滤结果都是一个 List
,对 Map
来说结果还是一个 Map
。
如果想使用否定条件来过滤集合,请使用 。它返回一个让谓词产生 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)
还有一些函数能够通过过滤给定类型的元素来缩小元素的类型:
filterIsInstance()
返回给定类型的集合元素。在一个List<Any>
上被调用时,filterIsInstance<T>()
返回一个List<T>
,从而让你能够在集合元素上调用T
类型的函数。
- 返回所有的非空元素。在一个
List<T?>
上被调用时,filterNotNull()
返回一个List<T: Any>
,从而让你能够将所有元素视为非空对象。
fun main() {
//sampleStart
val numbers = listOf(null, "one", "two", null)
numbers.filterNotNull().forEach {
println(it.length) // 对可空的 String 来说长度不可用
}
//sampleEnd
}
最后,有些函数只是针对集合元素简单地检测一个谓词:
- 如果至少有一个元素匹配给定谓词,那么
any()
返回true
。 - 如果所有元素都匹配给定谓词,那么 返回
true
。注意,在一个空集合上使用任何有效的谓词去调用all()
都会返回true
。这种行为在逻辑上被称为 vacuous truth。
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()
则相反。