1、 Kotlin 集合(2016 年诞生)
-
Kotlin 从第一天就支持:
- 高阶函数
- Lambda
- 函数式编程
所以 Kotlin 标准库直接给 List 增加了 扩展函数:
filtermapforEachflatMapsortedBy...
这些不是 List 原本的方法,是 Kotlin 事后扩展上去的!
2、 底层真相(超级重要)
❶ Kotlin:
kotlin
ini
list.filter { it % 2 == 0 }
filter 是一个扩展高阶函数源码大概长这样:
kotlin
kotlin
inline fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T> {
// 内部循环实现
}
✅ 不需要转任何流
✅ 直接调用
✅ 性能比 Java Stream 还好
❷ Java:
java
运行
scss
list.stream()
.filter(...)
.map(...)
必须先 .stream() 把集合转成 流对象 因为 Java List 本身没有 filter ()
3、Kotlin 为什么不用 Stream?
因为 Kotlin 有更强大的:
扩展函数 + 高阶函数 + inline 内联
-
Kotlin 拥有扩展函数,直接给 List 加 filter/map
-
Kotlin 支持高阶函数,天然支持 Lambda
-
Kotlin 标准库内置全部函数式 API
-
不需要像 Java 那样额外设计一套 Stream 流体系
4、Java 为什么必须 stream ()?
- Java 集合 历史包袱重
- Java 8 之前 没有函数式
- 不能破坏原有集合结构
- 只能新增一套 Stream API 来实现函数式
5、先看对比(一模一样的功能)
Java 代码(必须 collect)
java
运行
ini
List<Integer> list = List.of(1,2,3,4);
List<Integer> result = list.stream()
.filter(i -> i%2==0)
.map(i -> i*10)
.collect(Collectors.toList()); // 必须写!不写不执行
Kotlin 代码(不需要任何结尾函数)
kotlin
ini
val list = listOf(1,2,3,4)
val result = list.filter { it%2==0 }
.map { it*10 }
// 结束!自动返回 List<Int>,不用任何 collect
6、# 为什么 Java 必须写 collect?
因为 Java Stream 是惰性执行(懒加载)
- 你不调用
collect()/forEach()/count() - 中间操作(filter/map)根本不会执行!
- Stream 只是记录操作步骤,不调用终止方法就不干活
所以 Java 必须用 终止操作符 来触发执行并转回 List。
7、 为什么 Kotlin 不需要?
因为 Kotlin 的 filter/map 不是懒加载!是立即执行、立即返回新集合!
看一眼 Kotlin filter 源码 你就彻底懂了:
kotlin
kotlin
inline fun <T> List<T>.filter(...): List<T> {
val result = ArrayList<T>() // 直接创建新List
for (item in this) { // 立即遍历
if (predicate(item)) result.add(item)
}
return result // 直接返回新List
}
✔ 立即循环
✔ 立即返回新 List
✔ 不需要任何终止操作!
✔ 写完就是最终集合
8、最关键的 3 个区别
表格
| 操作 | Java Stream | Kotlin 集合函数 |
|---|---|---|
| 是否惰性 | 惰性(不 collect 不执行) | 立即执行 |
| 返回值 | Stream(不是 List) | 直接返回新 List |
| 是否需要结尾 | 必须 .collect() |
完全不需要 |
9、 Kotlin 中什么情况才需要结尾?
只有一种情况:你用了 Kotlin 的 asFlow() 或 sequence() 懒加载
正常写法 永远不用结尾!
10、 Flow 是什么?
异步版的 Sequence(协程专用)也是懒加载 ,必须调用末端挂起函数才执行。
Flow 必须写的「结尾方法」
kotlin
scss
collect{} // 最常用
first()
last()
count()
toList()
toSet()
single()
11、 Flow 正确写法(必须结尾)
kotlin
scss
val list = listOf(1,2,3,4)
// 懒加载流,不执行
val flow = list.asFlow()
.filter { it % 2 == 0 }
.map { it * 10 }
// ✅ 必须结尾(collect)才执行
lifecycleScope.launch {
flow.collect {
println(it)
}
}
12、 超级重要对比(一眼记住)
表格
| 类型 | 是否懒加载 | 必须结尾吗? | 结尾常用方法 |
|---|---|---|---|
| Kotlin 普通 List | ❌ 不懒 | ✅ 不用结尾 | 无 |
| Kotlin Sequence | ✅ 懒 | ✅ 必须结尾 | toList() / forEach / first() |
| Kotlin Flow | ✅ 懒 | ✅ 必须结尾 | collect() / toList() / first() |
| Java Stream | ✅ 懒 | ✅ 必须结尾 | collect() |
13、 最简单记忆口诀
普通集合:直接用,不用结尾****Sequence / Flow / JavaStream:懒加载,必须结尾!
14、你最常用的 3 个结尾(背会够用)
-
Sequence 结尾
kotlin
scss.toList() -
Flow 结尾
kotlin
sql.collect{} -
Java Stream 结尾
java
运行
less.collect(Collectors.toList())