JAVA 通用树形结构数据构建工具类

TreeNode

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
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
* 树结构
*/
@Data
@NoArgsConstructor
public class TreeNode implements Serializable {
private static final long serialVersionUID = -1506101868495287822L;

@ApiModelProperty(value = "节点Id")
private String id;

@ApiModelProperty(value = "节点名")
private String label;

@ApiModelProperty(value = "父节点Id")
private String parentId;

@ApiModelProperty(value = "子节点列表")
private List<TreeNode> children = new ArrayList<>();
}

第一种:单一实体

实现

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
/**
* 根据列表,构建树结构
*
* @param list 列表
* @param rootParentId 根节点的 parentId
* @return 树结构数据
*/
public static List<TreeNode> convert(List<TreeNode> list, String rootParentId) {
List<TreeNode> tree = new ArrayList<>();
Iterator<TreeNode> iterator = list.iterator();
while (iterator.hasNext()) {
TreeNode node = iterator.next();
String parentId = node.getParentId();
if (ObjectUtils.isEmpty(parentId) || rootParentId.equals(parentId)) {
tree.add(node);
iterator.remove();
}
}

for (TreeNode node : tree) {
List<TreeNode> children = TreeNode.getChildren(node, list);
node.getChildren().addAll(children);
}
return tree;
}

/**
* 获取子节点数据
*
* @param parentNode 父节点
* @param list 所有节点集合
* @return 返回子节点列表
*/
private static List<TreeNode> getChildren(TreeNode parentNode, List<TreeNode> list) {
List<TreeNode> children = new ArrayList<>();
Iterator<TreeNode> iterator = list.iterator();
while (iterator.hasNext()) {
TreeNode node = iterator.next();
// 如果当前节点 ID 与父节点 ID 一致,表示当前数据是该节点的子节点
if (parentNode.getId().equals(node.getParentId())) {
children.add(node);
iterator.remove();
}
}
// 递归调用
for (TreeNode node : children) {
// 调用自身方法,依次添加子节点数据
node.getChildren().addAll(getChildren(node, list));
}
return children;
}

使用例子

1
2
3
4
5
6
List<TreeNode> list = new ArrayList<>();
list.add(...);
...

// 构建树形结构数据
List<TreeNode> tree = convert(list, "-1");

第二种:任意实体

实现

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
public class TreeUtils {
/**
* 根据列表,构建树结构
*
* @param list 列表
* @param getIdFunction Id
* @param getParentIdFunction parentId
* @param setChildrenFunction children 列表
* @param rootParentId 跟节点父级 ID,一般为 0 或 -1
* @return 树结构数据
*/
public static <T> List<T> build(
List<T> list,
Function<T, ?> getIdFunction,
Function<T, ?> getParentIdFunction,
BiConsumer<T, List<T>> setChildrenFunction,
Long rootParentId
) {
List<T> tree = new ArrayList<>();
Iterator<T> iterator = list.iterator();
while (iterator.hasNext()) {
T node = iterator.next();
Object parentId = getParentIdFunction.apply(node);
if (ObjectUtils.isEmpty(parentId) || rootParentId.equals(parentId)) {
tree.add(node);
iterator.remove();
}
}

for (T node : tree) {
List<T> children = getChildren(node, list, getIdFunction, getParentIdFunction, setChildrenFunction);
if (!children.isEmpty()) {
setChildrenFunction.accept(node, children);
}
}
return tree;
}

/**
* 获取子节点数据
*
* @param parentNode 父节点
* @param list 所有节点集合
* @return 返回子节点列表
*/
private static <T> List<T> getChildren(
T parentNode,
List<T> list,
Function<T, ?> getIdFunction,
Function<T, ?> getParentFunction,
BiConsumer<T, List<T>> setChildrenFunction
) {
List<T> children = new ArrayList<>();
Iterator<T> iterator = list.iterator();
while (iterator.hasNext()) {
T node = iterator.next();
// 如果当前节点 ID 与父节点 ID 一致,表示当前数据是该节点的子节点
Object id = getIdFunction.apply(parentNode);
Object parentId = getParentFunction.apply(node);
if (id.toString().equals(parentId.toString())) {
children.add(node);
iterator.remove();
}
}
// 递归调用
for (T node : children) {
// 调用自身方法,依次添加子节点数据
List<T> childrenNodes = getChildren(node, list, getIdFunction, getParentFunction, setChildrenFunction);
if (!childrenNodes.isEmpty()) {
setChildrenFunction.accept(node, childrenNodes);
}
}
return children;
}
}

使用例子

1
2
3
4
5
6
List<TreeNode> list = new ArrayList<>();
list.add(...);
...

// 构建树形结构数据
List<TreeNode> tree = build(list, TreeNode::getId, TreeNode::getParentId, TreeNode::setChildren, "-1");
  • 本文作者: forever杨
  • 本文链接: https://blog.yl-online.top/posts/35652e2e.html
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。如果文章内容对你有用,请记录到你的笔记中。本博客站点随时会停止服务,请不要收藏、转载!