我们在写代码的时候,一般会遇到构建树结构接口,大部分我们都是通过多个嵌套循环来实现,可读性非常差,在代码规范中我们要极可能避免嵌套代码。在这里我们可以使用 Java8 中的 Stream 流一次性把数据查出来,然后通过流式处理,这样代码简单已读,非常好维护。
一、创建实体类
这里我们创建一个需要生成树状的实体类。
package com.piao.document;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @author piao
* @date 2024/1/12
*/
@Data
public class Tree implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
private Integer parentId;
private List<Tree> childList;
public Tree(Integer id, String name, Integer parentId) {
this.id = id;
this.name = name;
this.parentId = parentId;
}
public Tree(Integer id, String name, Integer parentId, List<Tree> childList) {
this.id = id;
this.name = name;
this.parentId = parentId;
this.childList = childList;
}
}
二、编写树结构代码
这里我们就简单使用 mian 方法来跑。
package com.piao.document;
import com.alibaba.fastjson.JSON;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* @author piao
* @date 2024/1/12
*/
public class MyStart {
public static void main(String[] args) {
List<Tree> trees = Arrays.asList(
new Tree(1, "根节点", 0),
new Tree(2, "子节点1", 1),
new Tree(3, "子节点1-1", 2),
new Tree(4, "子节点1-2", 2),
new Tree(5, "子节点1-3", 2),
new Tree(6, "子节点2", 1),
new Tree(7, "子节点2-1", 6),
new Tree(8, "子节点2-2", 6),
new Tree(9, "子节点2-2-1", 7),
new Tree(10, "子节点3", 1),
new Tree(11, "子节点3-1", 10),
new Tree(12, "子节点3-1-1", 11),
new Tree(13, "子节点3-1-2", 11)
);
List<Tree> list = trees.stream()
.filter(t -> 0 == t.getParentId())
.map(t -> {
t.setChildList(getChildrens(t, trees));
return t;
}).collect(Collectors.toList());
System.out.println(JSON.toJSON(list));
}
private static List<Tree> getChildrens(Tree root, List<Tree> all) {
List<Tree> children = all.stream()
.filter(t -> Objects.equals(t.getParentId(), root.getId()))
.map(t -> {
t.setChildList(getChildrens(t, all));
return t;
}).collect(Collectors.toList());
return children;
}
}
三、格式化打印结果
[
{
"name": "根节点",
"childList": [
{
"name": "子节点1",
"childList": [
{
"name": "子节点1-1",
"childList": [],
"id": 3,
"parentId": 2
},
{
"name": "子节点1-2",
"childList": [],
"id": 4,
"parentId": 2
},
{
"name": "子节点1-3",
"childList": [],
"id": 5,
"parentId": 2
}
],
"id": 2,
"parentId": 1
},
{
"name": "子节点2",
"childList": [
{
"name": "子节点2-1",
"childList": [
{
"name": "子节点2-2-1",
"childList": [],
"id": 9,
"parentId": 7
}
],
"id": 7,
"parentId": 6
},
{
"name": "子节点2-2",
"childList": [],
"id": 8,
"parentId": 6
}
],
"id": 6,
"parentId": 1
},
{
"name": "子节点3",
"childList": [
{
"name": "子节点3-1",
"childList": [
{
"name": "子节点3-1-1",
"childList": [],
"id": 12,
"parentId": 11
},
{
"name": "子节点3-1-2",
"childList": [],
"id": 13,
"parentId": 11
}
],
"id": 11,
"parentId": 10
}
],
"id": 10,
"parentId": 1
}
],
"id": 1,
"parentId": 0
}
]