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。

总结

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

相关文章

  • 实体类与String相互转换实现方式

    实体类与String相互转换实现方式

    文章记录了将实体类与String相互转换的方法,此方法适用于多种场景,如配置转换等,转换过程包括将实体类转为String保存至数据库,从数据库取出String再转为实体类,此经验仅供参考
    2026-04-04
  • Jmeter使用接口传递数据过程图解

    Jmeter使用接口传递数据过程图解

    这篇文章主要介绍了Jmeter使用接口传递数据过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • Spring中的Schedule动态添加修改定时任务详解

    Spring中的Schedule动态添加修改定时任务详解

    这篇文章主要介绍了Spring中的Schedule动态添加修改定时任务详解,可能有人会问,为啥不用Quartz,Quartz自然是非常方便强大的,但不是本篇要讲的内容,本篇就偏要使用SpringSchedule来实现动态的cron表达式任务,需要的朋友可以参考下
    2023-11-11
  • ElasticSearch之索引模板滚动索引实现详解

    ElasticSearch之索引模板滚动索引实现详解

    这篇文章主要为大家介绍了ElasticSearch之索引模板滚动索引实现详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • Java并发之BlockingQueue的使用

    Java并发之BlockingQueue的使用

    这篇文章主要介绍了Java并发之BlockingQueue的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • Spring Security 最佳实战指南

    Spring Security 最佳实战指南

    文章介绍了SpringSecurity框架的核心概念、配置、最佳实践、安全监控、生产环境配置以及常见安全漏洞与解决方案,通过实际案例,展示了如何在电商平台和金融系统中应用SpringSecurity,保护数据安全,强调安全是一个持续过程,需要不断更新和维护,感兴趣的朋友一起看看吧
    2026-04-04
  • 详解Spring AOP自定义可重复注解没有生效问题

    详解Spring AOP自定义可重复注解没有生效问题

    本文主要介绍了Spring AOP自定义可重复注解没有生效问题,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • spring boot + quartz集群搭建的完整步骤

    spring boot + quartz集群搭建的完整步骤

    这篇文章主要给大家介绍了关于spring boot + quartz集群搭建的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-05-05
  • Spring Boot循环依赖的症状和解决方案

    Spring Boot循环依赖的症状和解决方案

    循环依赖是指在Spring Boot 应用程序中,两个或多个类之间存在彼此依赖的情况,形成一个循环依赖链。这篇文章主要介绍了SpringBoot循环依赖的症状和解决方法
    2023-04-04
  • 详解Java多线程编程中线程的启动、中断或终止操作

    详解Java多线程编程中线程的启动、中断或终止操作

    在Java中start和tun方法可用被用来启动线程,而用interrupt方法来中断或终止线程,以下我们就来详解Java多线程编程中线程的启动、中断或终止操作
    2016-07-07

最新评论