使用 flatMap() 将嵌套的列表合并成一个新的列表

flatMap() 是Java 8中Stream API中的一个中间操作,用于将嵌套集合的元素合并成一个扁平化的流,其中每个元素都是由嵌套集合中的元素组成的。

flatMap() 方法的语法如下:<R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper)

其中,mapper 是将元素映射为流的一个函数。

下面是一个使用 flatMap() 操作的例子。假设有一个列表 List<List<String>> nestedList,它包含多个列表,每个列表又包含多个字符串。我们可以使用 flatMap() 方法将所有字符串合并成一个扁平的流:

ini 复制代码
List<String> flatList = nestedList.stream()                                  .flatMap(childList -> childList.stream())                                  .collect(Collectors.toList());

在上面的代码中,我们将 nestedList 转换为一个流,并使用 flatMap() 操作将每个子列表转换为一个子流。最后,我们将所有子流合并成一个扁平流,并将其收集到一个列表中。

需要注意的是,flatMap() 操作会返回一个新的 Stream 流对象,它并不会修改原来的流。因此,如果要将流进行多次扁平化,需要使用多个 flatMap() 操作或嵌套多个 flatMap() 操作。

flatMap() 是一个非常有用的中间操作,可以用于扁平化嵌套的集合,便于进行后续的数据处理。在实际开发中,我们可以将其用于各种场景,如树形结构数据的扁平化、多个集合的合并等等。

以下举例来说明,processNodeList 是一个 List<String> 类型的数据列表。接下来,我们对每个元素执行 map() 操作,将其转换为另一个 List 类型的数据列表。然后我们使用 flatMap() 将嵌套的列表合并成一个新的列表。

错误代码:

List processNodeId = Arrays.asList(processNodeList.stream() .map(item -> item.getProcessNodeList()) .flatMap(Arrays::stream) .toArray(String\[\]::new));

虽然这段代码使用了Java 8中的 Stream API,但它存在一些缺陷和可以改进的地方。以下是几个可能的问题:

  • 列表类型转换问题:在 map() 操作中,我们将一个 String 类型的元素映射到一个 List<String> 类型的列表。这可能会导致类型转换异常或不必要的内存消耗。

  • 重复的类型转换:在 flatMap() 操作中,我们将嵌套的列表转换为一个扁平的列表,但是我们使用了两次同样类型的转换操作。这可能会导致不必要的性能开销。

  • 不必要的数组转换:在 toArray() 操作中,我们将列表转换为一个新的 String[] 数组类型,以便将其添加到 filterParams 对象中。然而,这样的转换可能会导致不必要的内存开销和类型转换。

为了改进这段代码,我们可以使用以下方法:

  • 改变映射逻辑:我们可以改变 map() 操作,避免将元素映射到一个嵌套列表类型。例如,我们可以使用 map() 将列表中的元素映射到它们的 processNodeList 属性,然后使用 flatMap() 合并所有的列表元素。

  • 避免重复类型转换:我们可以使用 flatMap() 操作一次转换嵌套的列表,并将其转换为一个 Stream<String> 流,洁简流程。

  • 避免不必要的数组转换:我们可以将流直接转换为 List<String> 类型,而不必先将其转换为 String[] 数组类型再将其添加到 filterParams 对象中。

改进后的代码如下:

less 复制代码
List<String> processNodeId = processNodeList.stream()        .flatMap(item -> Arrays.stream(item.getProcessNodeList()))        .collect(Collectors.toList());```![](https://mutouzuo.oss-cn-hangzhou.aliyuncs.com/my/mudouzuo1.png)
相关推荐
Elastic 中国社区官方博客11 小时前
从建议到修复的 4 个阶段:使用 Elastic Workflows 实现人在回路中的自动化
运维·数据库·人工智能·后端·elasticsearch·ai·自动化
码视野11 小时前
基于 Spring Boot + Vue3 的【城市地下燃气管网微泄漏感知与相邻地下空间燃爆预警中台】设计与实现(含PRD/三端高保真源码/大屏)
java·前端·人工智能·spring boot·后端
Profile排查笔记12 小时前
指纹浏览器手机版怎么选?从本地 App 到云端 Android 的实现方式解析
前端·人工智能·后端·自动化
jufeng130712 小时前
STM32F103 IAP 实战:串口 Bootloader 分区升级,掉电断电不白写
后端
Lost of 程序猿12 小时前
ASP.NET Core 多租户架构深度实战:一套系统,管理一支船队
后端·架构·asp.net
深念Y12 小时前
视频平台架构重构:从微服务到可插拔基础设施
后端·微服务·云原生·架构·rabbitmq·音视频·rocketmq
汤姆yu12 小时前
基于Django的学习资料共享与智能推荐系统
后端·python·django·毕业设计·学习资料共享
Jesse_EC12 小时前
从 getStore() 到 execute() —— 单连接 IMAP 管理器的五次迭代记录
后端
摇滚侠12 小时前
《SpringBoot 3:入门与应用实战》第 9 章 使用 WebMvc 开发应用 阅读笔记 20
spring boot·笔记·后端
AI多Agent协作实战派12 小时前
AI多Agent协作系统实战(五十三):同一套系统,Linux沉默,Windows刷屏
后端