如何从Child树形结构生成CustomChild路径列表?
问题描述
我定义了如下Child类:
public class Child { private String id; private List<Child> children; // 省略getter、setter和构造方法 }
对应的JSON树形结构示例:
{ "id": "1", "children": [ { "id": "1_1", "children": [ { "id": "1_1_1" },{ "id": "1_1_2", "children": [ { "id": "1_1_2_1" } ] } ] },{ "id": "1_2", "children": [ { "id": "1_2_1", "children": [ { "id": "1_2_1_1" } ] } ] } ] }
希望获取该树形结构的所有根到叶子节点的完整路径,将每条路径转换为CustomChild类型的对象,最终组成列表。CustomChild类定义:
public class CustomChild { private String id; private CustomChild child; // 省略getter、setter和构造方法 }
期望输出列表示例:
[ { "id":"1", "child": { "id": "1_1", "child": { "id": "1_1_1" } } }, { "id":"1", "child": { "id": "1_1", "child": { "id": "1_1_2", "child": { "id": "1_1_2_1" } } } }, { "id":"1", "child": { "id": "1_2", "child": { "id": "1_2_1", "child": { "id": "1_2_1_1" } } } } ]
尝试递归实现但未成功,求可行方案。
解决方案
核心思路是通过深度优先遍历树形结构,记录每条从根到叶子的路径,再将路径转换为CustomChild的链式结构。
实现步骤
- 递归遍历每个节点,维护当前路径的节点列表;
- 当遍历到叶子节点(无子节点或子节点列表为空)时,将当前路径转换为
CustomChild链式对象,加入结果列表; - 非叶子节点则继续递归遍历其所有子节点,遍历完成后回溯路径,确保路径始终对应当前递归层级的节点链。
代码实现
import java.util.ArrayList; import java.util.List; public class TreeConverter { // 转换入口方法 public static List<CustomChild> convertToCustomChildList(Child root) { List<CustomChild> result = new ArrayList<>(); if (root == null) { return result; } List<Child> currentPath = new ArrayList<>(); currentPath.add(root); traverse(root, currentPath, result); return result; } // 递归遍历方法 private static void traverse(Child node, List<Child> currentPath, List<CustomChild> result) { List<Child> children = node.getChildren(); // 叶子节点:转换路径为CustomChild并加入结果 if (children == null || children.isEmpty()) { result.add(convertPathToCustomChild(currentPath)); return; } // 非叶子节点:遍历所有子节点 for (Child child : children) { currentPath.add(child); traverse(child, currentPath, result); // 回溯:移除当前子节点,回到父节点路径 currentPath.remove(currentPath.size() - 1); } } // 将路径列表转换为CustomChild链式结构 private static CustomChild convertPathToCustomChild(List<Child> path) { CustomChild prev = null; // 从路径末尾(叶子节点)往前构建链式结构,逻辑更简洁 for (int i = path.size() - 1; i >= 0; i--) { Child childNode = path.get(i); CustomChild custom = new CustomChild(); custom.setId(childNode.getId()); custom.setChild(prev); prev = custom; } return prev; } // Child类的getter/setter实现 static class Child { private String id; private List<Child> children; public String getId() { return id; } public void setId(String id) { this.id = id; } public List<Child> getChildren() { return children; } public void setChildren(List<Child> children) { this.children = children; } } // CustomChild类的getter/setter实现 static class CustomChild { private String id; private CustomChild child; public String getId() { return id; } public void setId(String id) { this.id = id; } public CustomChild getChild() { return child; } public void setChild(CustomChild child) { this.child = child; } } // 测试示例 public static void main(String[] args) { // 构建示例树形结构 Child leaf1_1_1 = new Child(); leaf1_1_1.setId("1_1_1"); Child leaf1_1_2_1 = new Child(); leaf1_1_2_1.setId("1_1_2_1"); Child node1_1_2 = new Child(); node1_1_2.setId("1_1_2"); node1_1_2.setChildren(List.of(leaf1_1_2_1)); Child node1_1 = new Child(); node1_1.setId("1_1"); node1_1.setChildren(List.of(leaf1_1_1, node1_1_2)); Child leaf1_2_1_1 = new Child(); leaf1_2_1_1.setId("1_2_1_1"); Child node1_2_1 = new Child(); node1_2_1.setId("1_2_1"); node1_2_1.setChildren(List.of(leaf1_2_1_1)); Child node1_2 = new Child(); node1_2.setId("1_2"); node1_2.setChildren(List.of(node1_2_1)); Child root = new Child(); root.setId("1"); root.setChildren(List.of(node1_1, node1_2)); // 转换并验证结果 List<CustomChild> result = convertToCustomChildList(root); // 可通过Jackson等JSON工具将result转为JSON,结果与期望一致 } }
关键说明
- 回溯机制:遍历子节点后必须从当前路径中移除该节点,否则路径会包含无关节点,导致转换结果错误;
- 反向构建链式结构:从叶子节点往根节点反向创建
CustomChild对象,只需将前一个节点设为当前节点的child,逻辑简单不易出错; - 空值处理:判断叶子节点时同时考虑
children为null或空列表的情况,避免空指针异常。
内容的提问来源于stack exchange,提问作者Nathan S
相关产品推荐
相关产品推荐

