Java实现递归查询树结构的示例代码

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

一、jar依赖

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

<dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <version>1.16.12</version>
</dependency>

二、树节点数据类

/**
 * TreeNode 树节点 (定义每一个节点的信息,即每一个节点对应一条数据信息)
 */
@Data
public class TreeNode {
 
 /** 节点ID */
 private Integer id;
 
 /** 父节点ID:顶级节点为0 */
 private Integer parentId;
 
 /** 节点名称 */
 private String label;
 
 /** 子节点 */
 private List<TreeNode> 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<TreeNode> nodeList = new ArrayList<>();
 
 /**
 * 构造方法
 * @param nodeList 将数据集合赋值给nodeList,即所有数据作为所有节点。
 */
 public TreeBuild(List<TreeNode> nodeList){
 this.nodeList = nodeList;
 }
 
 /**
 * 获取需构建的所有根节点(顶级节点) "0"
 * @return 所有根节点List集合
 */
 public List<TreeNode> getRootNode(){
 // 保存所有根节点(所有根节点的数据)
 List<TreeNode> rootNodeList = new ArrayList<>();
 // treeNode:查询出的每一条数据(节点)
 for (TreeNode treeNode : nodeList){
 // 判断当前节点是否为根节点,此处注意:若parentId类型是String,则要采用equals()方法判断。
 if (0 == treeNode.getParentId()) {
 // 是,添加
 rootNodeList.add(treeNode);
 }
 }
 return rootNodeList;
 }
 
 /**
 * 根据每一个顶级节点(根节点)进行构建树形结构
 * @return 构建整棵树
 */
 public List<TreeNode> buildTree(){
 // treeNodes:保存一个顶级节点所构建出来的完整树形
 List<TreeNode> treeNodes = new ArrayList<TreeNode>();
 // getRootNode():获取所有的根节点
 for (TreeNode treeRootNode : getRootNode()) {
 // 将顶级节点进行构建子树
 treeRootNode = buildChildTree(treeRootNode);
 // 完成一个顶级节点所构建的树形,增加进来
 treeNodes.add(treeRootNode);
 }
 return treeNodes;
 }
 
 /**
 * 递归-----构建子树形结构
 * @param pNode 根节点(顶级节点)
 * @return 整棵树
 */
 public TreeNode buildChildTree(TreeNode pNode){
 List<TreeNode> childTree = new ArrayList<TreeNode>();
 // 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<TreeNode> 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の甘乃迪原文地址:https://www.cnblogs.com/wyj-java/p/16932639.html

%s 个评论

要回复文章请先登录注册