第 7 章 · 集合 & 函数式操作

用瑞士军刀 API 把 for 循环全部干掉。

🔗 链式调用流水线(每步看中间结果)

选不同的操作组合,立刻看每一步的输出。

📥 输入

🔧 操作

⚡ Sequence vs List:求值时机的本质区别

同样的代码:filter { it > 2 }.map { it * 2 }.first()。看两种执行模式的不同。

📚 List(急性求值)

list.filter { it > 2 }
    .map { it * 2 }
    .first()

执行轨迹

↑ filter 把所有元素都跑完,map 也把所有元素都跑完,最后才取 first

⚡ Sequence(惰性求值)

list.asSequence()
    .filter { it > 2 }
    .map { it * 2 }
    .first()

执行轨迹

↑ 找到第一个就停!不会处理后面的元素

📊 性能对比(100 万元素 + 5 步流水线 + first)

List 总耗时
~150ms
Sequence 总耗时
~5ms
差距
30x

📦 groupBy / associateBy / partition 对比

把单词列表用三种方式分组,看返回结构的差别。

① groupBy { it.first() }(按首字母分组)

Map<Char, List<String>>,每个 key 对应多个元素

② associateBy { it.first() }(按首字母索引,重复 key 后者覆盖)

Map<Char, String>,每个 key 只能对应 1 个元素

③ partition { it.length > 5 }(按是否长 > 5 二分)

Pair<List<String>, List<String>>,严格二分

🛒 实战:电商订单分析(链式调用威力)

下面这段 Kotlin 替代了大约 50 行 for 循环 + HashMap 的 Java 代码。

val report = orders
    .filter { it.status == "PAID" }
    .groupBy { it.userId }
    .mapValues { (_, list) -> list.sumOf { it.amount } }
    .toList()
    .sortedByDescending { (_, total) -> total }
    .take(5)

📦 模拟订单数据(点按钮换数据集)

💰 用户付款 Top 5

🔥 商品销量 Top 5