正常项目开发中很多地方都需要用到树形结构,如分类,用户,权限等。而在数据库中,通常是使用一个parent_id这样一个字段来记录当前数据的父节点id。那么我们直接从数据库中查出来的是个list,就需要使用代码手动将list转成tree的结构了。我这里提供2种方法实现列表到树形结构的转换。
举一个用户的例子,用户实体User结构如下:@Data
@ToString
public class User {
/**
* 用户id
*/
private Long id;
/**
* 用户名
*/
private String name;
/**
* 父id,即上级id
*/
private Long parentId;
/**
* 子节点列表,即直系下级列表
*/
private List children;
/**
* 构造函数
* @param id
* @param name
* @param parentId
*/
public User(Long id, String name, Long parentId) {
this.id = id;
this.name = name;
this.parentId = parentId;
}
}
接下来我们需要造一些模拟数据,这里展示下用户间的层级结构,造数据的代码就不展示了:
我们使用2种办法实现列表转树形结构,这里对树的根节点的判断是通过parentId是否为null或者0来判断,且允许有多个根节点,即多棵树。
第一种:使用2次for循环遍历list数据public List listToTree1() {
List list = list();
List tree = new ArrayList<>();
for (User user : list) {
//找到根节点
if (user.getParentId() == null || user.getParentId().equals(0L)) {
tree.add(user);
}
List children = new ArrayList<>();
//再次遍历list,找到user的子节点
for (User node : list) {
if (node.getParentId().equals(user.getId())) {
children.add(node);
}
}
user.setChildren(children);
}
return tree;
}
原理:通过for循环是遍历所有数据,将根节点的数据加到树列表中,接着通过第二次for循环寻找所有元素的子节点
第二种:使用递归public List listToTree2() {
List list = list();
List tree = new ArrayList<>();
for (User user : list) {
//找到根节点
if (user.getParentId() == null || user.getParentId().equals(0L)) {
tree.add(findChildren(user, list));
}
}
return tree;
}
/**
* 查找user的子节点
* @param user
* @param list
* @return
*/
private User findChildren(User user, List list) {
List children = new ArrayList<>();
for (User node : list) {
if (node.getParentId().equals(user.getId())) {
//递归调用
children.add(findChildren(node, list));
}
}
user.setChildren(children);
return user;
}
原理:递归使用了2个函数,第一个listToTree2函数作用仅仅只是为了找到根节点,递归的函数是findChildren,这个函数会从list中查找属于user的子节点列表并设置到user中
我这里使用web请求来获取转换的结果:[
{
"id": 1,
"name": "董事长",
"parentId": 0,
"children": [
{
"id": 2,
"name": "赵经理",
"parentId": 1,
"children": [
{
"id": 4,
"name": "孙组长",
"parentId": 2,
"children": [
{
"id": 7,
"name": "小吴",
"parentId": 4,
"children": []
}
]
},
{
"id": 5,
"name": "李组长",
"parentId": 2,
"children": [
{
"id": 8,
"name": "小郑",
"parentId": 5,
"children": []
}
]
}
]
},
{
"id": 3,
"name": "钱经理",
"parentId": 1,
"children": [
{
"id": 6,
"name": "周组长",
"parentId": 3,
"children": []
}
]
}
]
}
]