本文详解如何利用 `flatmap` 与嵌套 `
stream
()` 链式调用,将三层嵌套结构(c → list
→ list)一次性转换为扁平化的 `list`,避免传统 for 循环,提升代码表达力与函数式编程能力。
在 Java 11 及以上版本中,面对具有层级关系的嵌套数据结构(如 C 持有 List,每个 B 又持有 List),若需生成所有 (A, B, C) 属性组合的扁平列表(如 List),核心挑战在于:
如何在单一流水线中跨越多层集合边界,同时捕获各层级的非集合字段(如 c1, c2, b1, a1)
。
答案是:
flatMap 是关键
。它用于将“流中的每个元素映射为一个新流,再将这些流合并为一个扁平流”,完美匹配“对每个 B,展开其全部 A”这一语义。
以下为完整、可直接使用的 Stream 实现:
✅
为什么这样可行?
Eclipse导入Android或其他的JAVA项目的正确方法 WORD版
本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
下载
立即学习
“
Java免费学习笔记(深入)
”;
c.getCList().stream() 创建 B 的流;
flatMap(b -> ...) 对每个 b 执行一个函数,该函数返回 Stream(由 b.getBList().stream().map(...) 构建);
flatMap 自动将所有 Stream 合并为单一 Stream,实现跨 B 边界的扁平化;
最终 collect(Collectors.toList()) 汇总结果。
⚠️
注意事项
:
c.getC1() 和 c.getC2() 在 lambda 中被
有效闭包捕获
——因 c 是方法局部变量且未被修改,符合 Java 的“实际上的 final”要求,安全可用;
flatMap 不可替换为 map:map 会生成 Stream>,导致类型不匹配;
若某 B 的 bList 为 null,需提前防护(如 Objects.requireNonNull(b.getBList()) 或使用 Optional.ofNullable(b.getBList()).orElse(Collections.emptyList()));
性能上,Stream 版本与双层 for 循环时间复杂度一致(O(n×m)),无额外开销,但可读性与维护性更优。
?
进阶提示(Java 11 兼容)
:
若需空安全或更清晰的链式表达,可封装为工具方法:
综上,通过合理运用 stream() + flatMap() + map() 的三级组合,即可优雅、高效、一次性地完成深层嵌套数据的解构与重组,真正践行函数式数据处理思想。
C c = someGetterForC();
List dList = c.getCList() // Stream
.stream()
.flatMap(b -> b.getBList() // 对每个 B,获取其 List
.stream() // 转为 Stream
.map(a -> new D( // 将每个 A 与上下文 B、C 字段组合
a.getA1(), // 来自 A
b.getB1(), // 来自当前 B
c.getC1(), // 来自顶层 C(闭包捕获)
c.getC2() // 来自顶层 C(闭包捕获)
)))
.collect(Collectors.toList()); public static List flattenToD(C c) {
return Optional.ofNullable(c)
.map(C::getCList)
.stream()
.flatMap(list -> list.stream())
.flatMap(b -> Optional.ofNullable(b.getBList())
.stream()
.flatMap(innerList -> innerList.stream())
.map(a -> new D(a.getA1(), b.getB1(), c.getC1(), c.getC2())))
.collect(Collectors.toList());
} 