Java中流式计算flatMap和map的区别及说明

 更新时间:2026年01月04日 09:15:51   作者:TTc_  
文章主要讲解了在Java中使用`Optional`类时,`map`和`flatMap`的区别,`map`会将返回值包装成`Optional`,导致嵌套的`Optional`结构,而`flatMap`会自动展平嵌套的`Optional`,最终得到一层`Optional`,因此,当函数返回`Optional`时,应使用`flatMap`而不是`map`

Java流式计算flatMap和map区别

示例代码

List<JSONObject> sflbmcResult = 
            apiService.getListByApi(522, condition).getData();

        ls_sflb = Optional.ofNullable(sflbmcResult)
                .flatMap(list -> list.stream()
                .filter(Objects::nonNull).findFirst())
                .map(json -> json.getString("SFLBMC"))
                .orElse("");

关键在于 findFirst() 返回的是 Optional<JSONObject>,而外层是 Optional<List<JSONObject>>。

使用 map 会得到嵌套的 Optional

Optional.ofNullable(sflbmcResult)  // Optional<List<JSONObject>>
    .map(list -> list.stream().findFirst())  
    // ❌ 返回类型:Optional<Optional<JSONObject>>(嵌套的Optional!)
    .map(json -> json.getString("SFLBMC"))  
    // ❌ 编译错误!json的类型是Optional<JSONObject>,不是JSONObject

使用 flatMap 会自动展平

Optional.ofNullable(sflbmcResult)  // Optional<List<JSONObject>>
    .flatMap(list -> list.stream().findFirst())  
    // ✅ 返回类型:Optional<JSONObject>(自动展平!)
    .map(json -> json.getString("SFLBMC"))  
    // ✅ 正常!json的类型是JSONObject

原因:flatMap 会“展平”嵌套的 Optional,而 map 不会。

对比示例

// 类型链分析
Optional<List<JSONObject>>  // 第一层Optional
    ↓
flatMap(list -> list.stream().findFirst())  
    // findFirst()返回:Optional<JSONObject>
    // flatMap自动展平:Optional<JSONObject> ✅
    ↓
map(json -> json.getString("SFLBMC"))  
    // json类型:JSONObject ✅
    // 返回:Optional<String>

如果使用 map:

Optional<List<JSONObject>>  // 第一层Optional
    ↓
map(list -> list.stream().findFirst())  
    // findFirst()返回:Optional<JSONObject>
    // map不展平:Optional<Optional<JSONObject>> ❌
    ↓
map(json -> json.getString("SFLBMC"))  
    // json类型:Optional<JSONObject> ❌
    // 编译错误!无法调用getString方法

结论:

  • map:函数返回普通值,包装成 Optional,会产生嵌套。
  • flatMap:函数返回 Optional,会“展平”嵌套,最终得到一层 Optional。

验证示例

// 类型链分析
Optional<List<JSONObject>>  // 第一层Optional
    ↓
flatMap(list -> list.stream().findFirst())  
    // findFirst()返回:Optional<JSONObject>
    // flatMap自动展平:Optional<JSONObject> ✅
    ↓
map(json -> json.getString("SFLBMC"))  
    // json类型:JSONObject ✅
    // 返回:Optional<String>

因此,当函数返回 Optional 时,应使用 flatMap 而不是 map。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • java语言自行实现ULID过程底层原理详解

    java语言自行实现ULID过程底层原理详解

    这篇文章主要为大家介绍了java语言自行实现ULID过程底层原理详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • Java函数式编程(二):集合的使用

    Java函数式编程(二):集合的使用

    这篇文章主要介绍了Java函数式编程(二):集合的使用,本文着重讲解了遍历列表的一些方法,需要的朋友可以参考下
    2014-09-09
  • java多线程模拟抢红包功能

    java多线程模拟抢红包功能

    这篇文章主要为大家详细介绍了java多线程模拟抢红包功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • Java中volatile防止指令重排

    Java中volatile防止指令重排

    volatile可以防止指令重排,在多线程环境下有时候我们需要使用volatile来防止指令重排,来保证代码运行后数据的准确性,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • 如何在 Java 中实现一个 redis 缓存服务

    如何在 Java 中实现一个 redis 缓存服务

    为什么要使用缓存?说到底是为了提高系统的运行速度。将用户频繁访问的内容存放在离用户最近,访问速度最快的地方,提高用户的响应速度。下面我们来一起深入学习一下吧
    2019-06-06
  • SpringBoot绿叶显示yml和端口问题及解决方法

    SpringBoot绿叶显示yml和端口问题及解决方法

    今天是解决报错的一天,首先在操作Springboot中的时候,有些朋友的yml显示的不是绿叶的图标,或者是配置了之后不生效的问题,今天就给大家分享SpringBoot绿叶显示yml和端口问题,感兴趣的朋友一起看看吧
    2023-01-01
  • IDEA快速创建SpringBoot项目的图文详解与避坑指南

    IDEA快速创建SpringBoot项目的图文详解与避坑指南

    IntelliJ IDEA作为Java开发者的‌首选IDE‌,深度集成Spring Boot支持,可一键生成项目骨架和智能配置依赖,下面我们就来看看如何零基础‌通过IDEA创建Spring Boot项目吧
    2025-05-05
  • Java集合中的Set之LinkedHashSet详解

    Java集合中的Set之LinkedHashSet详解

    这篇文章主要介绍了Java集合中的Set之LinkedHashSet详解,LinkedHashSet是Set集合的一个实现,具有set集合不重复的特点,同时具有可预测的迭代顺序,也就是我们插入的顺序,并且linkedHashSet是一个非线程安全的集合,需要的朋友可以参考下
    2023-09-09
  • Spring Boot编写拦截器教程实例解析

    Spring Boot编写拦截器教程实例解析

    这篇文章主要介绍了Spring Boot编写拦截器教程实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • resty upload无需依赖的文件上传与下载

    resty upload无需依赖的文件上传与下载

    这篇文章主要为大家介绍了resty upload中无需依赖的文件上传与下载过程,有需要的朋友可以借鉴参考下,希望能够有所帮助祝大家多多进步,早日升职加薪
    2022-03-03

最新评论