Kotlin Lambda & 集合高阶模块
1. Lambda 表达式
基础语法
kotlin
// 完整 Lambda:参数 -> 返回值
val sum: (Int, Int) -> Int = { a, b -> a + b }
sum(3, 4) // 7
// 单参数隐式 it
val double: (Int) -> Int = { it * 2 }
double(5) // 10
// 无参数
val hello: () -> String = { "Hello!" }
hello() // "Hello!"
// 返回 Unit
val printMsg: (String) -> Unit = { msg -> println(msg) }
匿名函数
kotlin
// 匿名函数:完整形式,有 return
val abs = fun(x: Int): Int {
return if (x >= 0) x else -x
}
// 匿名函数作为参数
fun execute(action: () -> Unit) {
action()
}
execute(fun() { println("匿名函数") })
简化写法优先级
kotlin
// 规则一:单参数 Lambda,可用 it 替代参数名
listOf(1, 2, 3).map { it * 2 }
// 规则二:最后一个参数是 Lambda,可移到括号外
listOf(1, 2, 3).map({ it * 2 }) // 标准
listOf(1, 2, 3).map { it * 2 } // 简化
// 规则三:唯一参数时,括号可省略
listOf(1, 2, 3).map { it * 2 }
// 多参数时:最后一个是 Lambda 才能外移
reduce { acc, item -> acc + item } // 正确
Lambda 返回值
kotlin
// Lambda 最后一行是返回值(隐式 return)
val len = { str: String -> str.length }
len("Kotlin") // 6
// 完整显式 return(用于嵌套 Lambda)
val weird = { x: Int ->
if (x > 0) return@weird x
-x
}
weird(-5) // 5
2. 集合框架
可变 vs 不可变
kotlin
// 不可变集合:创建后不可修改
val list: List<Int> = listOf(1, 2, 3)
// list.add(4) // 编译错误
// 可变集合
val mutable: MutableList<Int> = mutableListOf(1, 2, 3)
mutable.add(4) // OK
// 相互转换
val toMutable = list.toMutableList()
val toFixed = mutable.toList()
List
kotlin
// 不可变 List
val names = listOf("Alice", "Bob", "Charlie")
// 可变 List
val users = mutableListOf("Alice", "Bob")
users.add("Charlie")
users.removeAt(0)
// List 操作
names.first() // "Alice"
names.last() // "Charlie"
names.getOrNull(10) // null(安全越界)
names.getOrElse(10) { "Unknown" } // "Unknown"
names.subList(0, 2) // ["Alice", "Bob"]
Set
kotlin
// 不可变 Set(自动去重)
val colors = setOf("Red", "Green", "Blue", "Red") // ["Red", "Green", "Blue"]
// 可变 Set
val roles = mutableSetOf("Admin", "User")
roles.add("Guest")
roles.remove("User")
// 集合运算
val a = setOf(1, 2, 3, 4)
val b = setOf(3, 4, 5, 6)
a intersect b // {3, 4}(交集)
a union b // {1, 2, 3, 4, 5, 6}(并集)
a subtract b // {1, 2}(差集)
Map
kotlin
// 不可变 Map
val scores = mapOf("Alice" to 90, "Bob" to 85, "Charlie" to 92)
// 可变 Map
val config = mutableMapOf("theme" to "dark")
config["lang"] = "en"
config.remove("theme")
// 读取
scores["Alice"] // 90(不存在返回 null)
scores.getOrDefault("Tom", 0) // 0
// 遍历
for ((key, value) in scores) {
println("$key -> $value")
}
scores.forEach { (k, v) -> println("$k: $v") }
3. 集合高阶算子
map(转换)
kotlin
// map:对每个元素执行变换,返回新 List
val numbers = listOf(1, 2, 3, 4, 5)
numbers.map { it * 2 } // [2, 4, 6, 8, 10]
numbers.map { "数字: $it" } // ["数字: 1", "数字: 2", ...]
// mapIndexed:带索引变换
numbers.mapIndexed { index, value ->
"Index $index: $value"
} // ["Index 0: 1", "Index 1: 2", ...]
filter(过滤)
kotlin
numbers.filter { it > 3 } // [4, 5]
numbers.filterNot { it > 3 } // [1, 2, 3]
// filterIndexed
numbers.filterIndexed { index, value ->
index > 0 && value > 2
} // [3, 4, 5]
// 结合使用
numbers.map { it * 2 }.filter { it > 5 } // [6, 8, 10]
forEach / onEach
kotlin
// forEach:遍历(无返回值 Unit)
listOf(1, 2, 3).forEach { print(it) } // 123
// onEach:遍历同时返回原集合(用于链式操作)
listOf(1, 2, 3)
.onEach { println("Processing: $it") }
.map { it * 2 } // [2, 4, 6],同时打印 "Processing: 1/2/3"
find / first / last
kotlin
// find:返回第一个匹配元素,或 null
val nums = listOf(3, 1, 4, 1, 5, 9)
nums.find { it > 3 } // 4
nums.find { it > 100 } // null
// first:第一个元素(越界抛异常)
nums.first() // 3
nums.first { it > 3 } // 4
// last:最后一个元素
nums.last() // 9
nums.last { it < 5 } // 4
// firstOrNull / lastOrNull(安全版)
nums.firstOrNull { it > 100 } // null
flatten / flatMap(扁平化)
kotlin
// flatten:展平嵌套集合
val nested = listOf(
listOf(1, 2),
listOf(3, 4),
listOf(5)
)
nested.flatten() // [1, 2, 3, 4, 5]
// flatMap:先 map 再 flatten
val words = listOf("Hello", "World")
words.flatMap { it.toList() } // [H, e, l, l, o, W, o, r, l, d]
// 实际场景:获取用户的所有角色
users.flatMap { it.roles } // 所有用户的角色集合
take / drop(截取)
kotlin
numbers.take(3) // [1, 2, 3](取前 3)
numbers.drop(3) // [4, 5](去除前 3)
numbers.takeLast(2) // [4, 5](取后 2)
numbers.dropLast(2) // [1, 2, 3](去除后 2)
// chunked:分块
numbers.chunked(2) // [[1, 2], [3, 4], [5]]
numbers.chunked(2) { it.sum() } // [3, 7, 5]
distinct / sorted
kotlin
listOf(1, 2, 2, 3, 1, 3).distinct() // [1, 2, 3]
listOf(3, 1, 4, 1, 5, 9).sorted() // [1, 1, 3, 4, 5, 9]
listOf(3, 1, 4, 1, 5, 9).sortedDescending() // [9, 5, 4, 3, 1, 1]
// sortBy / sortedBy(自定义排序)
listOf("bb", "a", "ccc").sortedBy { it.length } // [a, bb, ccc]
listOf("bb", "a", "ccc").sortedByDescending { it.length } // [ccc, bb, a]
groupBy / partition
kotlin
// groupBy:按条件分组
val names = listOf("Alice", "Bob", "Anna", "Brian")
names.groupBy { it.first() } // {A=[Alice, Anna], B=[Bob, Brian]}
// partition:按条件分为两部分
numbers.partition { it > 3 } // Pair([4, 5], [1, 2, 3])
val (pass, fail) = numbers.partition { it >= 3 }
associate(转换为 Map)
kotlin
// associate:元素转 Pair 形成 Map
listOf("Alice", "Bob", "Charlie")
.associate { it to it.length } // {Alice=5, Bob=3, Charlie=7}
// associateBy:只用 key 生成 Map
listOf("Alice", "Bob", "Charlie")
.associateBy { it.first() } // {A=Alice, B=Bob, C=Charlie}
// associateWith:只用 value 生成 Map
listOf("Alice", "Bob", "Charlie")
.associateWith { it.length } // {Alice=5, Bob=3, Charlie=7}
4. 聚合算子 reduce / fold
kotlin
// reduce:累积运算(无初始值,第一项作起点)
listOf(1, 2, 3, 4, 5).reduce { acc, item ->
acc + item
} // 15(1+2+3+4+5)
listOf(1, 2, 3, 4, 5).reduce { acc, item ->
acc * item
} // 120(1*2*3*4*5)
// ⚠️ 空集合 reduce 会抛异常
// listOf<Int>().reduce { acc, item -> acc + item } // 异常
// fold:有初始值,从初始值开始累积
listOf(1, 2, 3, 4, 5).fold(10) { acc, item ->
acc + item
} // 25(10+1+2+3+4+5)
// fold 用于字符串拼接
listOf("a", "b", "c").fold("Start:") { acc, s -> "$acc$s" } // "Start:abc"
// sumOf:数值求和(更简洁)
listOf(1, 2, 3, 4, 5).sumOf { it * 2 } // 30
其他聚合算子
kotlin
// count:计数
numbers.count { it > 3 } // 2
// sum / average
numbers.sum() // 15
numbers.average() // 3.0
// min / max
numbers.min() // 1
numbers.max() // 5
numbers.minByOrNull { -it } // 5(取最大值的元素)
numbers.maxByOrNull { -it } // 1(取最小值的元素)
// any / all / none(全称量词)
numbers.any { it > 3 } // true(任意匹配)
numbers.all { it > 0 } // true(全部匹配)
numbers.none { it < 0 } // true(无匹配)
5. 序列 sequence 懒求值
集合 vs 序列
kotlin
// 集合:每一步立即求值(急求值)
listOf(1, 2, 3, 4, 5)
.map { it * 2 } // [2, 4, 6, 8, 10](立即计算)
.filter { it > 5 } // [6, 8, 10](立即计算)
.take(2) // [6, 8](立即计算)
// 序列:懒求值(按需计算),链中每个操作不会立即执行
listOf(1, 2, 3, 4, 5)
.asSequence()
.map { it * 2 } // 不立即计算
.filter { it > 5 } // 不立即计算
.take(2) // 不立即计算
.toList() // 这里才真正执行:[6, 8]
性能对比:大数据量
kotlin
import kotlin.system.measureTimeMillis
val bigList = (1..1_000_000).toList()
// 急求值:每步都遍历整个集合
val time1 = measureTimeMillis {
bigList
.map { it * 2 }
.filter { it > 1000 }
.take(10)
.toList()
}
println("Eager: $time1 ms") // 约 100+ ms
// 懒求值:只处理必需的元素
val time2 = measureTimeMillis {
bigList
.asSequence()
.map { it * 2 }
.filter { it > 1000 }
.take(10)
.toList()
}
println("Lazy: $time2 ms") // 约 1-5 ms
序列操作符
kotlin
// asSequence():集合转序列
listOf(1, 2, 3).asSequence()
// generateSequence:生成无限序列
val naturals = generateSequence(1) { it + 1 }
naturals.take(5).toList() // [1, 2, 3, 4, 5]
// 斐波那契数列
val fibonacci = generateSequence(Pair(0, 1)) {
Pair(it.second, it.first + it.second)
}.map { it.first }
fibonacci.take(10).toList() // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
// sequenceOf:手动创建序列
val seq = sequenceOf(1, 2, 3, 4, 5)
何时用序列
kotlin
// 场景一:大数据量 + 截断操作(take/drop/first)
(1..10_000_000)
.asSequence()
.map { it * 2 }
.filter { it % 1000 == 0 }
.take(100)
.toList()
// 场景二:链式操作且中间不产生新集合
// 序列避免创建中间集合(map/filter 各自产生中间 List)
// 注意:元素少时序列额外开销可能更大,简单场景用集合即可
listOf(1, 2, 3).map { it * 2 } // 小数据量直接用集合
6. 综合实战示例
kotlin
// 场景:Android 中获取活跃用户列表
data class User(val name: String, val age: Int, val isActive: Boolean)
// 过滤 -> 转换 -> 排序 -> 取前 10
val activeUsers = users
.filter { it.isActive }
.map { "${it.name} (${it.age})" }
.sortedBy { it }
.take(10)
// 场景:分组统计
val grouped = products
.groupBy { it.category }
.mapValues { (_, items) -> items.sumOf { it.price } }
// 场景:多层嵌套扁平化
orders
.flatMap { order ->
order.items.map { item ->
"${order.customer} -> ${item.name}"
}
}
// 场景:序列处理大数据
(1..10_000_000L)
.asSequence()
.filter { it % 2 == 0L }
.map { it * it }
.take(1000)
.reduce { acc, l -> acc + l }
快速对照表
| 算子 | 作用 | 返回类型 |
|---|---|---|
map |
转换每个元素 | List<R> |
filter |
过滤元素 | List<T> |
forEach |
遍历(无返回) | Unit |
onEach |
遍历(返回原集合) | List<T> |
find |
找第一个匹配 | T? |
first |
第一个/匹配元素 | T |
flatten |
展平嵌套集合 | List<T> |
flatMap |
转换+展平 | List<R> |
reduce |
累积(无初始值) | T |
fold |
累积(有初始值) | R |
take |
取前 N 项 | List<T> |
drop |
去除前 N 项 | List<T> |
groupBy |
按条件分组 | Map<K, List<V>> |
partition |
分为两部分 | Pair<List, List> |
distinct |
去重 | List<T> |
sortedBy |
自定义排序 | List<T> |
asSequence |
转懒序列 | Sequence<T> |
性能口诀:
- 小数据随便用,大数据加
asSequence() - 链式截断(take/drop/first)优先考虑序列
- 避免在
map/filter中执行重操作(序列可延迟发现问题)