Kotlin高阶函数和Java 8 lambda的区别:

16 阅读3分钟

1、 Kotlin 集合(2016 年诞生)

  • Kotlin 从第一天就支持:

    • 高阶函数
    • Lambda
    • 函数式编程

所以 Kotlin 标准库直接给 List 增加了 扩展函数

  • filter
  • map
  • forEach
  • flatMap
  • sortedBy...

这些不是 List 原本的方法,是 Kotlin 事后扩展上去的!

2、 底层真相(超级重要)

❶ Kotlin:

kotlin

list.filter { it % 2 == 0 }

filter 是一个扩展高阶函数源码大概长这样:

kotlin

inline fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T> {
    // 内部循环实现
}

✅ 不需要转任何流

✅ 直接调用

✅ 性能比 Java Stream 还好

❷ Java:

java

运行

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 ()?

  1. Java 集合 历史包袱重
  2. Java 8 之前 没有函数式
  3. 不能破坏原有集合结构
  4. 只能新增一套 Stream API 来实现函数式

5、先看对比(一模一样的功能)

Java 代码(必须 collect)

java

运行

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

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

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 StreamKotlin 集合函数
是否惰性惰性(不 collect 不执行)立即执行
返回值Stream(不是 List)直接返回新 List
是否需要结尾必须 .collect()完全不需要

9、 Kotlin 中什么情况才需要结尾?

只有一种情况:你用了 Kotlin 的 asFlow() 或 sequence() 懒加载

正常写法 永远不用结尾

10、 Flow 是什么?

异步版的 Sequence(协程专用)也是懒加载,必须调用末端挂起函数才执行。

Flow 必须写的「结尾方法」

kotlin

collect{}       // 最常用
first()
last()
count()
toList()
toSet()
single()

11、 Flow 正确写法(必须结尾)

kotlin

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 个结尾(背会够用)

  1. Sequence 结尾

    kotlin

    .toList()
    
  2. Flow 结尾

    kotlin

    .collect{}
    
  3. Java Stream 结尾

    java

    运行

    .collect(Collectors.toList())