• Java实现递归查询树结构


            我们在实际开发中,肯定会用到树结构,如部门树、菜单树等等。Java后台利用递归思路进行构建树形结构数据,返回给前端,能以下拉菜单等形式进行展示。今天,咱们就来说说怎么样将List集合转换成TreeList

    一、jar依赖

            为了简化代码,引入Lombok的Jar包,可省略实体类set()、get()方法。

    
         org.projectlombok
         lombok
         1.16.12
    

    二、树节点数据类

    /**
     *  TreeNode 树节点 (定义每一个节点的信息,即每一个节点对应一条数据信息)
     */
    @Data
    public class TreeNode {
     
        /** 节点ID */
        private Integer id;
     
        /** 父节点ID:顶级节点为0 */
        private Integer parentId;
     
        /** 节点名称 */
        private String label;
     
        /** 子节点 */
        private List children;
     
        public TreeNode(Integer id, Integer parentId, String label) {
            this.id = id;
            this.parentId = parentId;
            this.label = label;
        }
    }

    三、构建树形类

    理解思路(个人):

    1、首先获取所有的根节点(顶级节点),即根节点的parentId = 0。

    2、根据每一个根节点,与所有节点集合(数据)进行判断,当前节点是否为其下的子节点。

    3、若是,则递归调用构建树形;若不是,则表明该节点不属于其下子节点。

    4、应继续循环判断节点父子关系,直到所有节点与根节点判断完毕。

    /**
     *  BuildTree 构建树形结构
     */
    public class TreeBuild {
        
        // 保存参与构建树形的所有数据(通常数据库查询结果)
        public List nodeList = new ArrayList<>();
     
        /**
         *  构造方法
         *  @param nodeList 将数据集合赋值给nodeList,即所有数据作为所有节点。
         */
        public TreeBuild(List nodeList){
            this.nodeList = nodeList;
        }
     
        /**
         *   获取需构建的所有根节点(顶级节点) "0"
         *   @return 所有根节点List集合
         */
        public List getRootNode(){
            // 保存所有根节点(所有根节点的数据)
            List rootNodeList = new ArrayList<>();
            // treeNode:查询出的每一条数据(节点)
            for (TreeNode treeNode : nodeList){
                // 判断当前节点是否为根节点,此处注意:若parentId类型是String,则要采用equals()方法判断。
                if (0 == treeNode.getParentId()) {
                    // 是,添加
                    rootNodeList.add(treeNode);
                }
            }
            return rootNodeList;
        }
     
        /**
         *  根据每一个顶级节点(根节点)进行构建树形结构
         *  @return  构建整棵树
         */
        public List buildTree(){
            // treeNodes:保存一个顶级节点所构建出来的完整树形
            List treeNodes = new ArrayList();
            // getRootNode():获取所有的根节点
            for (TreeNode treeRootNode : getRootNode()) {
                // 将顶级节点进行构建子树
                treeRootNode = buildChildTree(treeRootNode);
                // 完成一个顶级节点所构建的树形,增加进来
                treeNodes.add(treeRootNode);
            }
            return treeNodes;
        }
     
        /**
         *  递归-----构建子树形结构
         *  @param  pNode 根节点(顶级节点)
         *  @return 整棵树
         */
        public TreeNode buildChildTree(TreeNode pNode){
            List childTree = new ArrayList();
            // nodeList:所有节点集合(所有数据)
            for (TreeNode treeNode : nodeList) {
                // 判断当前节点的父节点ID是否等于根节点的ID,即当前节点为其下的子节点
                if (treeNode.getParentId().equals(pNode.getId())) {
                    // 再递归进行判断当前节点的情况,调用自身方法
                    childTree.add(buildChildTree(treeNode));
                }
            }
            // for循环结束,即节点下没有任何节点,树形构建结束,设置树结果
            pNode.setChildren(childTree);
            return pNode;
        }
     
    }

    四、测试案例

    /**
     *  TreeController 树控制层
     *  方式:传递所有数据集合作为参数,调用buildTree()构建树形。
     */
    @RestController
    @RequestMapping("/tree")
    public class TreeController {
     
        @GetMapping("/treeTest")
        public AjaxResult treeTest(){
     
            // 模拟测试数据(通常为数据库的查询结果)
            List treeNodeList = new ArrayList<>();
            treeNodeList.add(new TreeNode(1,0,"顶级节点A"));
            treeNodeList.add(new TreeNode(2,0,"顶级节点B"));
            treeNodeList.add(new TreeNode(3,1,"父节点是A"));
            treeNodeList.add(new TreeNode(4,2,"父节点是B"));
            treeNodeList.add(new TreeNode(5,2,"父节点是B"));
            treeNodeList.add(new TreeNode(6,3,"父节点的ID是3"));
     
            // 创建树形结构(数据集合作为参数)
            TreeBuild treeBuild = new TreeBuild(treeNodeList);
            // 原查询结果转换树形结构
            treeNodeList = treeBuild.buildTree();
            // AjaxResult:个人封装返回的结果体
            return AjaxResult.success("测试数据",treeNodeList);
        }
    }

    结果:

    {
    	"msg”:“ 测试数据”,
    	"code": 200,
    	"data": [
      		  {
    			"id": 1,
    			"parentId": 0,
    			"label":"顶级节点A",
    			"children": [
       		 {
    					"id": 3,
        				"parentId": 1,
    					"label":“ 父节点是A"
    					"children": [
    						"id": 6,
    						"parentId": 3,
    						"label":“ 父节点的ID是3
    					}
    				]
    			}
    		]
    	}, 
    	{
    		"id": 2,
    		"parentId": 0,
    		"labe1":“ 顶级节点B",
    		"children": [{
    				"id": 4,
    				"parentId": 2,
    				"label":“ 父节点是B"
    			},
    			{
    				"id": 5,
    				"parentId": 2,
    				"label":" 父节点是B
    			}
    		]
    	}
    ]
    }

    本文介绍Java后台构建树形结构数据的设计思路及实现,如有不对可以或更好的方案,欢迎指出和讨论。 

  • 相关阅读:
    c语言入门---调试技巧
    专利交底书怎么写 -
    .net core appsettings.json 配置 http 无法访问
    Hack The Box-Monitored
    OFDM同步技术
    远程控制与遥控器控制耦合
    UE5 C++ TPS开发 学习记录(六)
    C++多态
    酷家乐基于 Crane EHPA 的弹性落地实践
    LoRa和LoRaWAN有什么区别?工业网关能用吗?
  • 原文地址:https://www.cnblogs.com/wyj-java/p/16932639.html