集合操作概述
Kotlin 标准库提供了多种多样的函数,用于对集合执行操作。这包括简单的操作,例如获取或添加元素,以及更复杂的操作,包括搜索、排序、过滤、转换等等。
扩展函数与成员函数
集合操作在标准库中有两种声明方式:集合接口的成员函数和扩展函数。
成员函数定义了对集合类型至关重要的操作。例如,Collection
包含 isEmpty()
函数,用于检测其是否为空;List
包含 get()
函数,用于索引访问元素,等等。
当你创建自己的集合接口实现时,必须实现它们的成员函数。为了方便创建新实现,请使用标准库中集合接口的骨架实现:AbstractCollection
、AbstractList
、AbstractSet
、AbstractMap
及其可变对应物。
其他集合操作被声明为扩展函数。这些是过滤、转换、排序以及其他集合处理函数。
常见操作
常见操作适用于只读集合和可变集合。常见操作分为以下几组:
这些页面中描述的操作返回其结果,而不影响原始集合。例如,过滤操作会生成一个新集合,其中包含所有符合过滤谓词的元素。此类操作的结果应存储在变量中,或以其他方式使用,例如传递给其他函数。
fun main() {
val numbers = listOf("one", "two", "three", "four")
numbers.filter { it.length > 3 } // numbers 未受影响,结果丢失
println("numbers 仍然是 $numbers")
val longerThan3 = numbers.filter { it.length > 3 } // 结果存储在 longerThan3 中
println("长度超过 3 个字符的 numbers 是 $longerThan3")
}
对于某些集合操作,可以选择指定目标对象。目标是可变集合,函数会将结果项附加到其中,而不是在新对象中返回它们。为了执行带目标的操作,有单独的函数,其名称带有 To
后缀,例如 filterTo()
而不是 filter()
,或者 associateTo()
而不是 associate()
。这些函数将目标集合作为附加形参。
fun main() {
val numbers = listOf("one", "two", "three", "four")
val filterResults = mutableListOf<String>() //目标对象
numbers.filterTo(filterResults) { it.length > 3 }
numbers.filterIndexedTo(filterResults) { index, _ -> index == 0 }
println(filterResults) // 包含两个操作的结果
}
为了方便,这些函数会返回目标集合,因此你可以直接在函数调用的相应实参中创建它:
fun main() {
val numbers = listOf("one", "two", "three", "four")
// 直接将数字过滤到一个新的哈希 set 中,
// 从而消除结果中的重复项
val result = numbers.mapTo(HashSet()) { it.length }
println("不同的项长度是 $result")
}
带目标(destination)的函数可用于过滤、关联、分组、展平等操作。关于目标操作的完整列表,请参见 Kotlin 集合参考。
写入操作
对于可变集合,还有会改变集合状态的写入操作。此类操作包括添加、删除和更新元素。写入操作列在写入操作以及List 特有的操作和 Map 特有的操作的相应章节中。
对于某些操作,有成对的函数用于执行相同的操作:一个原地应用操作,另一个将结果作为单独的集合返回。例如,sort()
原地排序可变集合,因此其状态会改变;sorted()
则创建一个新集合,其中包含相同元素但按排序后的顺序排列。
fun main() {
val numbers = mutableListOf("one", "two", "three", "four")
val sortedNumbers = numbers.sorted()
println(numbers == sortedNumbers) // false
numbers.sort()
println(numbers == sortedNumbers) // true
}