一、前提
- pId需要传入用来确认第一级的父节点,而且pId可以为null。
- 树实体类必须实现:TreeNode接口
- MyTreeVo必须有这三个属性:id、pId、children
- 可以根据不同需求,配置TreeNode和MyTreeVo中固定的属性
二、代码
| public interface TreeNode { |
| String getId(); |
| String getpId(); |
| List getChildren(); |
| } |
- 需要将pId作为参数传入,在方法中添加一个pId参数,用于确认第一级的父节点。
-- 这个示例代码中,buildTree方法接收两个参数,一个是泛型类型的参数List,另一个是pId,用于确认第一级的父节点。在找到所有的根节点后,我们需要对每个根节点调用buildChildren方法,递归构建子节点。
-- 以便支持传入的pId作为顶级节点
| public class TreeBuilder { |
| |
| |
| |
| |
| public static <T extends TreeNode> List<T> buildTree(List<T> nodes, String pId) { |
| List<T> roots = new ArrayList<>(); |
| for (T node : nodes) { |
| if (node.getId().equals(pId) || (node.getParentId() == null && (pId == null || pId.equals(node.getId())))) { |
| roots.add(node); |
| } |
| } |
| for (T root : roots) { |
| buildChildren(root, nodes); |
| } |
| return roots; |
| } |
| |
| private static <T extends TreeNode> void buildChildren(T node, List<T> nodes) { |
| for (T child : nodes) { |
| if (child.getParentId() != null && child.getParentId().equals(node.getId())) { |
| node.getChildren().add(child); |
| buildChildren(child, nodes); |
| } |
| } |
| } |
| } |
- 构建到几级
-- 如果再增加一个参数,构建到树的第几层该如何实现?
-- 根据需求,如果增加一个参数来控制构建到树的第几层,可以在buildChildren方法中添加一个level参数,用于记录当前节点的层数。在递归构建子节点时,如果当前节点的层数小于指定的层数,则继续递归构建子节点,否则停止递归。以下是修改后的Java示例代码:
| public class TreeBuilder { |
| |
| |
| |
| |
| public static <T extends TreeNode> List<T> buildTree(List<T> nodes, String pId, int level) { |
| List<T> roots = new ArrayList<>(); |
| for (T node : nodes) { |
| if (node.getId().equals(pId) || (node.getParentId() == null && (pId == null || pId.equals(node.getId())))) { |
| roots.add(node); |
| } |
| } |
| for (T root : roots) { |
| buildChildren(root, nodes, level, 1); |
| } |
| return roots; |
| } |
| |
| private static <T extends TreeNode> void buildChildren(T node, List<T> nodes, int level, int currentLevel) { |
| if (currentLevel >= level) { |
| return; |
| } |
| for (T child : nodes) { |
| if (child.getParentId() != null && child.getParentId().equals(node.getId())) { |
| if (node.getChildren() == null) { |
| node.setChildren(new ArrayList<>()); |
| } |
| node.getChildren().add(child); |
| buildChildren(child, nodes, level, currentLevel + 1); |
| } |
| } |
| } |
| } |
| |
三、使用
1、实现TreeNode接口
| public class MyTreeVo implements TreeNode { |
| |
| |
| |
| |
| private String id; |
| |
| |
| |
| |
| private String pId; |
| |
| |
| |
| |
| private List<MyTreeVo> children = Lists.newArrayList(); |
| |
| |
| |
| public List<MyTreeVo> getChildren() { |
| return children; |
| } |
| |
| public String getId() { |
| return id; |
| } |
| |
| public String getpId() { |
| return pId; |
| } |
| |
| |
2、使用
-- pId可以传入null,也可以传入需要从哪个节点(X)开始构造的 X的id
-- pId比如可以传入3、样例中的 “二、噢噢噢噢”的id=“e6ee51485389495cb923a122be800012”。然后构建出来的,就是“二、噢噢噢噢”的下级树
| List<MyTreeVo> tree = TreeUtilQz.buildTree(vos,null); |
| |
3、样例
| { |
| "data": [ |
| { |
| "id": "e6ee51485389495cb923a122be800011", |
| "pId": "", |
| "name": "一、钢管钢管", |
| "children": [ |
| { |
| "id": "e6ee51485389495cb923a122be800014", |
| "pId": "e6ee51485389495cb923a122be800011", |
| "name": "(二)嘎嘎嘎嘎嘎", |
| "children": [] |
| }, |
| { |
| "id": "e6ee51485389495cb923a122be800013", |
| "pId": "e6ee51485389495cb923a122be800011", |
| "name": "(一)顶顶顶顶", |
| "children": [] |
| } |
| ] |
| }, |
| { |
| "id": "e6ee51485389495cb923a122be800012", |
| "pId": "", |
| "name": "二、噢噢噢噢", |
| "children": [ |
| { |
| "id": "e6ee51485389495cb923a122be800015", |
| "pId": "e6ee51485389495cb923a122be800012", |
| "name": "二的下级", |
| "children": [ |
| { |
| "id": "e6ee51485389495cb923a122be800016", |
| "pId": "e6ee51485389495cb923a122be800015", |
| "name": "二的下级的下级", |
| "children": [] |
| } |
| ] |
| } |
| ] |
| } |
| ] |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了