Kotlin 集合
Kotlin 的集合框架功能强大且易于使用。本章将详细介绍 List、Set、Map 以及各种操作函数。
集合类型概述
集合分类
| 类型 | 描述 | 可变性 |
|---|---|---|
| List | 有序集合,可重复 | List / MutableList |
| Set | 无序集合,不重复 | Set / MutableSet |
| Map | 键值对 | Map / MutableMap |
List
创建 List
fun main() {
// 1. 使用 listOf 创建不可变 List
val list1 = listOf(1, 2, 3)
val list2 = listOf("a", "b", "c")
// 2. 使用 mutableListOf 创建可变 List
val mutableList = mutableListOf(1, 2, 3)
mutableList.add(4)
mutableList.remove(1)
// 3. 使用 arrayListOf
val arrayList = arrayListOf(1, 2, 3)
// 4. 指定类型
val emptyList = emptyList<Int>()
val listWithDefault = List(5) { it * 2 } // [0, 2, 4, 6, 8]
println(list1) // [1, 2, 3]
println(mutableList) // [2, 3, 4]
}
访问元素
fun main() {
val list = listOf("a", "b", "c", "d", "e")
// 通过索引访问
println(list[0]) // a(可能越界)
println(list.get(0)) // a
// 安全访问
println(list.getOrNull(10)) // null
println(list.getOrElse(10) { "default" }) // default
// 第一个/最后一个
println(list.first()) // a
println(list.last()) // e
// 带条件的第一个/最后一个
println(list.first { it > "b" }) // c
println(list.last { it < "d" }) // c
}
修改 List
fun main() {
val list = mutableListOf(1, 2, 3, 4, 5)
// 添加元素
list.add(6)
list.addAll(listOf(7, 8))
list.add(0, 0) // 指定位置插入
// 删除元素
list.remove(1) // 删除第一个匹配的
list.removeAt(0) // 删除指定位置
list.clear() // 清空
// 修改
list[0] = 10
list.set(1, 20)
// 批量操作
list.addAll(0, listOf(100, 200)) // 位置插入集合
println(list)
}
Set
创建 Set
fun main() {
// 不可变 Set
val set1 = setOf(1, 2, 3, 2, 1) // 自动去重
println(set1) // [1, 2, 3]
// 可变 Set
val mutableSet = mutableSetOf(1, 2, 3)
mutableSet.add(4)
mutableSet.add(2) // 重复元素无效
// hashSetOf - 基于哈希表
val hashSet = hashSetOf(1, 2, 3)
// linkedSetOf - 保持插入顺序
val linkedSet = linkedSetOf(1, 2, 3)
// sortedSetOf - 排序
val sortedSet = sortedSetOf(3, 1, 2)
println(sortedSet) // [1, 2, 3]
}
Set 操作
fun main() {
val set1 = setOf(1, 2, 3, 4)
val set2 = setOf(3, 4, 5, 6)
// 并集
println(set1.union(set2)) // [1, 2, 3, 4, 5, 6]
println(set1 + set2) // [1, 2, 3, 4, 5, 6]
// 交集
println(set1.intersect(set2)) // [3, 4]
println(set1 * set2) // [3, 4]
// 差集
println(set1.subtract(set2)) // [1, 2]
println(set1 - set2) // [1, 2]
// 对称差集
println(set1.symmetricDifference(set2)) // [1, 2, 5, 6]
}
Map
创建 Map
fun main() {
// 不可变 Map
val map1 = mapOf("a" to 1, "b" to 2, "c" to 3)
// 可变 Map
val mutableMap = mutableMapOf("a" to 1, "b" to 2)
mutableMap["c"] = 3
mutableMap.put("d", 4)
// 使用 to 指定键值对
val map2 = mapOf(
"name" to "Tom",
"age" to 25
)
// hashMapOf - 哈希表
val hashMap = hashMapOf("a" to 1)
// linkedMapOf - 保持顺序
val linkedMap = linkedMapOf("a" to 1, "b" to 2)
// sortedMapOf - 键排序
val sortedMap = sortedMapOf("b" to 2, "a" to 1)
println(map1) // {a=1, b=2, c=3}
}
访问 Map
fun main() {
val map = mapOf("a" to 1, "b" to 2, "c" to 3)
// 访问值
println(map["a"]) // 1
println(map.get("a")) // 1
println(map["z"]) // null
// 安全访问
println(map.getOrDefault("z", 0)) // 0
println(map.getOrElse("z") { 99 }) // 99
// 检查键/值
println(map.containsKey("a")) // true
println(map.containsValue(1)) // true
println("a" in map) // true
println(1 in map.values) // true
// 获取所有键/值
println(map.keys) // [a, b, c]
println(map.values) // [1, 2, 3]
println(map.entries) // [a=1, b=2, c=3]
}
修改 Map
fun main() {
val map = mutableMapOf("a" to 1, "b" to 2)
// 添加/修改
map["c"] = 3
map.put("d", 4)
map.putAll(mapOf("e" to 5, "f" to 6))
// 删除
map.remove("a")
map.remove("b", 2) // 仅当值匹配时删除
// 清空
// map.clear()
println(map) // {c=3, d=4, e=5, f=6}
}
集合操作函数
遍历
fun main() {
val list = listOf(1, 2, 3, 4, 5)
// forEach
list.forEach { println(it) }
// forEachIndexed
list.forEachIndexed { index, value ->
println("Index: $index, Value: $value")
}
// Map 遍历
val map = mapOf("a" to 1, "b" to 2)
map.forEach { (key, value) ->
println("$key = $value")
}
}
转换函数
fun main() {
val list = listOf(1, 2, 3, 4, 5)
// map - 转换每个元素
println(list.map { it * 2 }) // [2, 4, 6, 8, 10]
println(list.mapIndexed { i, v -> i + v }) // [1, 3, 5, 7, 9]
// flatMap - 扁平化
val words = listOf("hello", "world")
println(words.flatMap { it.toList() }) // [h, e, l, l, o, w, o, r, l, d]
// associate - 转换为 Map
val names = listOf("Tom", "Jerry", "Spike")
println(names.associateWith { it.length }) // {Tom=3, Jerry=5, Spike=5}
println(names.associate { it to it.length }) // {Tom=3, Jerry=5, Spike=5}
// groupBy - 分组
println(listOf(1, 2, 3, 4, 5).groupBy { it % 2 }) // {0=[2, 4], 1=[1, 3, 5]}
}
过滤函数
fun main() {
val list = listOf(1, 2, 3, 4, 5)
// filter - 过滤
println(list.filter { it > 3 }) // [4, 5]
println(list.filterNot { it > 3 }) // [1, 2, 3]
// filterIndexed
println(list.filterIndexed { i, v -> i % 2 == 0 }) // [1, 3, 5]
// filterNotNull
val listWithNull = listOf(1, null, 2, null, 3)
println(listWithNull.filterNotNull()) // [1, 2, 3]
// partition - 分离
val (even, odd) = list.partition { it % 2 == 0 }
println(even) // [2, 4]
println(odd) // [1, 3, 5]
// take/skip
println(list.take(3)) // [1, 2, 3]
println(list.drop(2)) // [3, 4, 5]
println(list.takeWhile { it < 3 }) // [1, 2]
println(list.dropWhile { it < 3 }) // [3, 4, 5]
}
元素检查
fun main() {
val list = listOf(1, 2, 3, 4, 5)
// any - 是否有满足条件的元素
println(list.any { it > 3 }) // true
println(list.any { it > 10 }) // false
// all - 是否所有元素都满足条件
println(list.all { it > 0 }) // true
println(list.all { it > 3 }) // false
// none - 是否没有满足条件的元素
println(list.none { it > 10 }) // true
// contains
println(list.contains(3)) // true
println(3 in list) // true
// count
println(list.count { it > 3 }) // 2
}
聚合函数
fun main() {
val list = listOf(1, 2, 3, 4, 5)
// sum / average
println(list.sum()) // 15
println(list.average()) // 3.0
// min / max
println(list.minOrNull()) // 1
println(list.maxOrNull()) // 5
// fold / reduce
println(list.fold(0) { acc, i -> acc + i }) // 15 (初始值0)
println(list.reduce { acc, i -> acc + i }) // 15 (无初始值)
// foldRight / reduceRight
println(list.foldRight(0) { i, acc -> i + acc }) // 15
// groupingBy + eachCount
val words = listOf("apple", "banana", "cherry", "apricot")
println(words.groupingBy { it.first() }.eachCount()) // {a=2, b=1, c=1}
}
排序函数
fun main() {
val list = listOf(3, 1, 4, 1, 5, 9, 2, 6)
// sorted - 升序
println(list.sorted()) // [1, 1, 2, 3, 4, 5, 6, 9]
// sortedDescending - 降序
println(list.sortedDescending()) // [9, 6, 5, 4, 3, 2, 1, 1]
// sortedBy / sortedByDescending
val data = listOf("ab", "a", "abc", "")
println(data.sortedBy { it.length }) // [, ab, abc]
println(data.sortedByDescending { it.length }) // [abc, ab, a, ]
// reversed
println(list.reversed()) // [6, 2, 9, 5, 4, 1, 3, 1]
// shuffled
println(list.shuffled()) // 随机顺序
}
Sequence(序列)
Sequence 用于处理大数据集,避免创建中间集合:
fun main() {
// 创建 Sequence
val sequence = sequenceOf(1, 2, 3, 4, 5)
// 从函数生成
val generated = generateSequence(0) { it + 2 }.take(5) // 0, 2, 4, 6, 8
// 从集合
val fromList = listOf(1, 2, 3).asSequence()
// 链式操作(惰性求值)
val result = sequenceOf(1, 2, 3, 4, 5)
.filter { it > 2 } // 不立即执行
.map { it * 2 } // 不立即执行
.take(2) // 不立即执行
.toList() // 触发执行
println(result) // [6, 8]
}
集合与数组互转
fun main() {
// List 转数组
val list = listOf(1, 2, 3)
val array = list.toIntArray()
val array2 = list.toTypedArray()
// 数组转 List
val intArray = intArrayOf(1, 2, 3)
val listFromArray = intArray.toList()
// Set 与 List 互转
val set = setOf(1, 2, 3)
val listFromSet = set.toList()
val setFromList = listOf(1, 1, 2, 2, 3).toSet()
}
小结
本章我们学习了:
- List:有序集合,可重复
- Set:无序集合,不重复
- Map:键值对
- 创建集合:listOf, mutableListOf, setOf, mapOf 等
- 访问元素:索引、安全访问
- 修改集合:添加、删除、修改
- 操作函数:map, filter, forEach 等
- 聚合函数:sum, fold, reduce 等
- 排序:sorted, reversed, shuffled
- Sequence:惰性求值,优化大数据处理
练习
- 创建 List,筛选出偶数并计算平方和
- 使用 associate 将名字列表转换为"名字 -> 长度"的 Map
- 使用 groupBy 按首字母分组
- 对数据类列表按多个字段排序
- 使用 Sequence 处理大数据,演示惰性求值