• JAVA-递归构建树形结构 嵌套子节点返参给前端 && 获取某节点下所有叶子节点 && 获取某节点下叶节点(没有子节点的节点)



    JAVA项目中递归根据parentId构建树形结构,嵌套其children子节点返参给前端。获取某个根节点下所有叶子节点;获取某个根节点下叶节点(没有子节点的节点);只获取叶子节点id。

    构建树

    tagId为节点id;parentId为其父节点id;tagName为节点名称;children为子节点List类型。

    getRootNode() 是获取所有的根节点,我们将父节点ID(parentId)为0的判为根节点。

    buildChildTree() 获取所有节点集合,判断当前节点的父节点ID(parentId)是否等于根节点的ID(tagId),即当前节点为其下的子节点。再递归进行判断当前节点的情况,调用自身方法。

    buildTree() 根据每个根节点来构建树形结构

        /**
         *   获取需构建的所有根节点(顶级节点) "0"
         *   @return 所有根节点List集合
         */
        public List<TagRequestVO> getRootNode(){chre
            // 保存所有根节点(所有根节点的数据)
            List<TagRequestVO> rootNodeList = new ArrayList<>();
            // treeNode:查询出的每一条数据(节点)
            List<Tag> nodeList = tagMapper.selectList(null);
            for (Tag treeNode : nodeList){
                // 判断当前节点是否为根节点,
                if (treeNode.getParentId().equals("0")) {
                    // 是,添加
                    //tagId为节点id;parentId为其父节点id;tagName为节点名称
                    TagRequestVO response = new TagRequestVO();
                    response.setTagId(treeNode.getTagId());
                    response.setTagName(treeNode.getTagName());
                    response.setParentId(treeNode.getParentId());
                    rootNodeList.add(response);
                }
            }
            return rootNodeList;
        }
    
        /**
         *  递归-----构建子树形结构
         *  @param  pNode 根节点(顶级节点)
         *  @return 整棵树
         */
        public TagRequestVO buildChildTree(TagRequestVO pNode){
            List<TagRequestVO> childTree = new ArrayList<>();
            // nodeList:所有节点集合(所有数据)
            List<Tag> nodeList = tagMapper.selectList(null);
            for (Tag treeNode : nodeList) {
                // 判断当前节点的父节点ID是否等于根节点的ID,即当前节点为其下的子节点
                //tagId为节点id;parentId为其父节点id;tagName为节点名称
                if (treeNode.getParentId().equals(pNode.getTagId())) {
                    // 再递归进行判断当前节点的情况,调用自身方法
                    TagRequestVO response = new TagRequestVO();
                    response.setTagId(treeNode.getTagId());
                    response.setTagName(treeNode.getTagName());
                    response.setParentId(treeNode.getParentId());
                    childTree.add(buildChildTree(response));
                }
            }
            // for循环结束,即节点下没有任何节点,树形构建结束,设置树结果
            pNode.setChildren(childTree);
            return pNode;
        }
    
    	/**
         *  根据每一个顶级节点(根节点)进行构建树形结构
         *  @return  构建整棵树
         */
        public List<TagRequestVO> buildTree(){
            // treeNodes:保存一个顶级节点所构建出来的完整树形
            List<TagRequestVO> treeNodes = new ArrayList<>();
            // getRootNode():获取所有的根节点
            for (TagRequestVO treeRootNode : getRootNode()) {
                // 将顶级节点进行构建子树
                treeRootNode = buildChildTree(treeRootNode);
                // 完成一个顶级节点所构建的树形,增加进来
                treeNodes.add(treeRootNode);
            }
            return treeNodes;
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    在没有子节点时的children会返回空数组[];如果想要为空时不反悔可以在VO加上改注释就不会返回了。

    //为空不返回
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    //为null不返回
    @JsonInclude(JsonInclude.Include.NON_NULL)
    
    • 1
    • 2
    • 3
    • 4

    获取某节点下的所有叶子节点

    树形构建与上述相差不大,只是需要在获取根节点函数(getRootNodeByTag())中加上指定筛选所需要的节点id(tagId)。子树形结构(buildChildTreeByTag())其实与上面的一模一样,构建树形后,再去匹配其下的叶子节点。

    getAllChildren()获取其所有叶子节点。

    getTreeTagId()获取其所有叶子节点ID(tagId)。

    	/**
         *   获取需构建的根节点,根据根节点tagId匹配
         *   @return 所有根节点List集合
         */
        public List<TagRequestVO> getRootNodeByTag(String tagId){
            QueryWrapper<Tag> wrapper = new QueryWrapper<>();
            wrapper.and(w -> w.eq("tag_id", tagId).or().eq("parent_id", tagId));
            List<Tag> nodeList = tagMapper.selectList(wrapper);
            List<TagRequestVO> rootNodeList = new ArrayList<>();
            for (Tag treeNode : nodeList){
                TagRequestVO response = new TagRequestVO();
                if (treeNode.getParentId().equals("0")) {
                    response.setTagId(treeNode.getTagId());
                    rootNodeList.add(response);
                }
            }
            return rootNodeList;
        }
    
    	/**
         *  递归-----构建子树形结构
         *  @param  pNode 根节点(顶级节点)
         *  @return 整棵树
         */
        public TagRequestVO buildChildTreeByTag(TagRequestVO pNode){
            List<TagRequestVO> childTree = new ArrayList<>();
            List<Tag> nodeList = tagMapper.selectList(null);
            for (Tag treeNode : nodeList) {
                if (treeNode.getParentId().equals(pNode.getTagId())) {
                    TagRequestVO response = new TagRequestVO();
                    response.setTagId(treeNode.getTagId());
                    response.setParentId(treeNode.getParentId());
                    childTree.add(buildChildTreeByTag(response));
                }
            }
            pNode.setChildren(childTree);
            return pNode;
        }
    
    	/**
         *  根据每一个顶级节点(根节点)进行构建树形结构
         *  @return  构建整棵树
         */
        public List<TagRequestVO> buildTreeByTag(String tagId){
            List<TagRequestVO> treeNodes = new ArrayList<>();
            for (TagRequestVO treeRootNode : getRootNodeByTag(tagId)) {
                treeRootNode = buildChildTreeByTag(treeRootNode);
                treeNodes.add(treeRootNode);
            }
            return treeNodes;
        }
    
    	//获取该节点下的所有叶子节点
        private List<TagRequestVO> getAllChildren(TagRequestVO tagRequestVO,List returnList){
        	//获取叶子节点children
            List<TagRequestVO> childrenList = tagRequestVO.getChildren();
            if(childrenList!=null && childrenList.size()>0){
                for(TagRequestVO children : childrenList){
                	//递归
                    getAllChildren(children,returnList);
                    returnList.add(children);
                }
            }
            return returnList;
        }
    
    	//获取该节点下的所有叶子节点tagId
    	public List<String> getTreeTagId(String tagId){
            List returnList = new ArrayList();
            List<TagRequestVO> tag = getAllChildren(buildTreeByTag(tagId).get(0), returnList);
            List<String> tagIdList = new ArrayList<>();
            for(TagRequestVO tagChildren : tag){
                tagIdList.add(tagChildren.getTagId());
            }
            return tagIdList;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76

    获取某节点下没有子节点的叶节点(没有children)

    树形构建与上述相差不大,只是需要在获取根节点函数(getRootNodeByTag())中加上指定筛选所需要的节点id(tagId)。子树形结构(buildChildTreeByTag())其实与上面的一模一样,构建树形后,再去匹配其下的叶子节点。

    getChildren()获取其所有的叶节点,要注意判断条件的没有children(叶子节点)。

    getTreeChildrenTagId获取其所有叶节点ID(tagId)。

    	/**
         *   获取需构建的根节点,根据根节点tagId匹配
         *   @return 所有根节点List集合
         */
        public List<TagRequestVO> getRootNodeByTag(String tagId){
            QueryWrapper<Tag> wrapper = new QueryWrapper<>();
            wrapper.and(w -> w.eq("tag_id", tagId).or().eq("parent_id", tagId));
            List<Tag> nodeList = tagMapper.selectList(wrapper);
            List<TagRequestVO> rootNodeList = new ArrayList<>();
            for (Tag treeNode : nodeList){
                TagRequestVO response = new TagRequestVO();
                if (treeNode.getParentId().equals("0")) {
                    response.setTagId(treeNode.getTagId());
                    rootNodeList.add(response);
                }
            }
            return rootNodeList;
        }
    
    	/**
         *  根据每一个顶级节点(根节点)进行构建树形结构
         *  @return  构建整棵树
         */
        public List<TagRequestVO> buildTreeByTag(String tagId){
            List<TagRequestVO> treeNodes = new ArrayList<>();
            for (TagRequestVO treeRootNode : getRootNodeByTag(tagId)) {
                treeRootNode = buildChildTreeByTag(treeRootNode);
                treeNodes.add(treeRootNode);
            }
            return treeNodes;
        }
    
    
    	/**
         *  递归-----构建子树形结构
         *  @param  pNode 根节点(顶级节点)
         *  @return 整棵树
         */
        public TagRequestVO buildChildTreeByTag(TagRequestVO pNode){
            List<TagRequestVO> childTree = new ArrayList<>();
            List<Tag> nodeList = tagMapper.selectList(null);
            for (Tag treeNode : nodeList) {
                if (treeNode.getParentId().equals(pNode.getTagId())) {
                    TagRequestVO response = new TagRequestVO();
                    response.setTagId(treeNode.getTagId());
                    response.setParentId(treeNode.getParentId());
                    childTree.add(buildChildTreeByTag(response));
                }
            }
            pNode.setChildren(childTree);
            return pNode;
        }
    
    	//获取该节点下 没有子节点的(没有children) 叶子节点
        private List<TagRequestVO> getChildren(TagRequestVO tagRequestVO,List returnList){
            List<TagRequestVO> childrenList = tagRequestVO.getChildren();
    		// 退出递归的条件 只有一层维度结构
            if(childrenList==null || childrenList.size()<=0){
                returnList.add(tagRequestVO);
            }else{
    			// 有多层维度结果
                for(TagRequestVO children : childrenList){
                    getChildren(children,returnList);
                }
            }
            return returnList;
        }
        
    	//获取该节点下 没有子节点的(没有children) 叶子节点的tagId
        public List<String> getTreeChildrenTagId(String tagId){
            List returnList = new ArrayList();
            List<TagRequestVO> tag = getChildren(buildTreeByTag(tagId).get(0), returnList);
            List<String> childrenTagIdList = new ArrayList<>();
            for(TagRequestVO tagChildren : tag){
                childrenTagIdList.add(tagChildren.getTagId());
            }
            return childrenTagIdList;
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79

    参考:https://blog.csdn.net/a18505947362/article/details/122458089

    https://blog.csdn.net/weixin_36368404/article/details/115783785?spm=1001.2101.3001.6650.13&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-13-115783785-blog-124102788.pc_relevant_multi_platform_whitelistv4&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-13-115783785-blog-124102788.pc_relevant_multi_platform_whitelistv4&utm_relevant_index=14

  • 相关阅读:
    C++Prime Plus(7)
    SAS常用函数
    jmeter跨平台运行csv等文件
    IntelliJ IDEA 2022创建Maven项目
    ARM内核地址对齐访问如何理解
    23. python 条件判断嵌套
    【C++11】std::function 包装器(又叫适配器),std::bind 绑定
    JavaScript-变量的作用域、let、const详解
    C++原子变量
    索引优化分析_索引介绍
  • 原文地址:https://blog.csdn.net/weixin_44436677/article/details/127589077