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

1、 Kotlin 集合(2016 年诞生)

  • Kotlin 从第一天就支持:

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

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

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

这些不是 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 ()?

  1. Java 集合 历史包袱重
  2. Java 8 之前 没有函数式
  3. 不能破坏原有集合结构
  4. 只能新增一套 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 个结尾(背会够用)

  1. Sequence 结尾

    kotlin

    scss 复制代码
    .toList()
  2. Flow 结尾

    kotlin

    sql 复制代码
    .collect{}
  3. Java Stream 结尾

    java

    运行

    less 复制代码
    .collect(Collectors.toList())
相关推荐
千里马学框架3 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台3 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone3 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc3 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo3 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077003 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼3 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone3 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen3 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone3 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui