集合的各种操作(转换、过滤、分组、排序等)
Kotlin 标准库提供了丰富的集合操作函数,可以高效地完成数据转换、过滤、分组和排序等任务。这些操作大多基于高阶函数实现,能够以声明式的方式处理集合数据。
1. 转换操作
map 与 mapIndexed
将集合中的每个元素转换为另一种形式:
val numbers = listOf(1, 2, 3)
val squared = numbers.map { it * it } // [1, 4, 9]
带索引的版本:
val indexedSquares = numbers.mapIndexed { index, num ->
"Index $index: ${num * num}"
}
// ["Index 0: 1", "Index 1: 4", "Index 2: 9"]
flatMap 与 flatten
处理嵌套集合:
val nestedList = listOf(listOf(1, 2), listOf(3, 4))
val flattened = nestedList.flatten() // [1, 2, 3, 4]
val transformed = nestedList.flatMap { it.map { num -> num * 2 } } // [2, 4, 6, 8]
2. 过滤操作
filter 与 filterNot
val evenNumbers = numbers.filter { it % 2 == 0 } // [2]
val oddNumbers = numbers.filterNot { it % 2 == 0 } // [1, 3]
带索引的过滤
val filteredByIndex = numbers.filterIndexed { index, _ -> index > 0 } // [2, 3]
类型过滤
val mixedList = listOf(1, "two", 3.0)
val stringsOnly = mixedList.filterIsInstance<String>() // ["two"]
3. 分组操作
groupBy
val words = listOf("apple", "banana", "cherry")
val byLength = words.groupBy { it.length }
// {5=["apple"], 6=["banana", "cherry"]}
groupingBy (惰性分组)
val grouping = words.groupingBy { it.first() }
println(grouping.eachCount()) // {'a'=1, 'b'=1, 'c'=1}
4. 排序操作
自然排序
val sortedNumbers = numbers.sorted() // 升序
val sortedDescending = numbers.sortedDescending() // 降序
自定义排序
val people = listOf("Alice" to 30, "Bob" to 25)
val byAge = people.sortedBy { it.second } // 按年龄升序
val byNameLength = people.sortedWith(compareBy { it.first.length })
5. 聚合操作
基本聚合
val sum = numbers.sum() // 6
val average = numbers.average() // 2.0
val max = numbers.maxOrNull() // 3
reduce 与 fold
val product = numbers.reduce { acc, num -> acc * num } // 6
val sumWithInitial = numbers.fold(10) { acc, num -> acc + num } // 16
6. 其他实用操作
去重
val duplicates = listOf(1, 2, 2, 3)
val distinct = duplicates.distinct() // [1, 2, 3]
切片与窗口
val sublist = numbers.slice(1..2) // [2, 3]
val slidingWindow = numbers.windowed(2) // [[1, 2], [2, 3]]
分区
val (evens, odds) = numbers.partition { it % 2 == 0 }
// evens = [2], odds = [1, 3]
性能考虑
- 链式调用会创建中间集合,对于大数据集考虑使用
asSequence() - 排序操作的时间复杂度通常为 O(n log n)
- 查找操作(如
first())在列表中是 O(1),在序列中是惰性的
示例:综合应用
data class Person(val name: String, val age: Int, val city: String)
val people = listOf(
Person("Alice", 25, "New York"),
Person("Bob", 30, "Chicago"),
Person("Charlie", 25, "New York")
)
val result = people
.filter { it.age > 20 }
.groupBy { it.city }
.mapValues { (_, group) ->
group.sortedByDescending { it.age }
.map { it.name }
}
// {"New York"=["Alice", "Charlie"], "Chicago"=["Bob"]}
