flatmap可配合递归函数扁平化树结构:如allnodes返回所有节点(含自身及后代),leaves仅返回叶子节点,nodeswithdepth添加深度信息;它只展开第一层嵌套,精准匹配树形递归需求。

flatMap 本身不直接支持递归遍历树形结构,但它可以和递归函数配合,简洁地“拍平”嵌套的子节点,生成一维的扁平化结果(比如所有节点、所有叶子、带路径的节点等)。
核心思路:用 flatMap 替代 map + flat(1)
树形结构通常有类似这样的形式:
const tree = { id: 1, name: 'A', children: [ { id: 2, name: 'A-1', children: [] }, { id: 3, name: 'A-2', children: [ { id: 4, name: 'A-2-1', children: [] } ] } ] };要获取所有节点(含自身),可写一个递归函数,对每个节点返回 [当前节点, ...递归处理子节点],再用 flatMap 自动展开一层 —— 这比先 map 再手动 flat() 更干净。
获取所有节点(深度优先顺序)
定义递归函数,对单个节点返回包含自己和全部后代的数组:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 当前节点自身必须作为数组第一个元素(保证被保留)
- 子节点数组调用同一函数后,用
flatMap展开,避免嵌套 - children 为空或不存在时,返回空数组,不影响展开
const result = allNodes(tree); // 所有节点按 DFS 顺序排列
只提取叶子节点(无 children 的节点)
逻辑稍作调整:如果是叶子,返回 [node];否则只递归子节点,不包含当前节点:
- 检查
node.children?.length === 0或!node.children - 是叶子 → 返回
[node](让 flatMap 保留它) - 非叶子 → 返回
node.children.flatMap(leaves)(跳过当前节点)
if (!node.children || node.children.length === 0) return [node];
return node.children.flatMap(leaves);
};
带层级或路径信息的展开(例如添加 depth 字段)
flatMap 不限制返回内容类型,可传入额外参数(如当前 depth),在递归中累加:
- 初始调用传入
depth = 0 - 每个节点包装为
{ ...node, depth } - 递归子节点时传
depth + 1
{ ...node, depth },
...(node.children?.flatMap(child => nodesWithDepth(child, depth + 1)) ?? [])
];
注意:flatMap 只展开**第一层**嵌套,刚好匹配“当前节点 + 子树结果数组”的结构,不会过度展平。如果树极深,需注意调用栈限制,此时可改用栈模拟递归。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










