比较通用的一套树形结构构建工具类。
1.属性节点的基类,包含三个主要属性,当前节点id、父节点id、子节点集合
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* 树结构节点
* @Author dong
* @Date 2023/11/20 下午 3:27
*/
@Data
public class TreeNode<T extends TreeNode> {
/**
* 当前节点id
*/
protected Object id;
/**
* 父节点id
*/
protected Object parentId;
/**
* 子节点列表
*/
protected List<T> children;
public void add(T node) {
if(children == null){
children = new ArrayList<>();
}
children.add(node);
}
}
2.构建树形结构的工具类,总共三个实现,参数都是节点集合+根节点id。
三个实现直接看代码吧。个人比较喜欢用的是一个celerityBuild,n*2即可构建出树
import lombok.experimental.UtilityClass;
import java.util.*;
/**
* 树工具类
* @Author dong
* @Date 2023/11/20 下午 3:29
*/
@UtilityClass
public class TreeUtil {
/**
* 双循环构建树 n*2
* @Author dong
* @Date 2023/11/20 下午 3:25
* @param treeNodes
* @param root
* @return java.util.List<T>
*/
public <T extends TreeNode> List<T> celerityBuild(List<T> treeNodes, Object root) {
List<T> result = new ArrayList<>();
Map<Object, TreeNode> nodeMap = new HashMap<>();
for (T treeNode : treeNodes) {
nodeMap.put(treeNode.getId(),treeNode);
}
for (T treeNode : treeNodes) {
if (Objects.equals(root, treeNode.getParentId())) {
result.add(treeNode);
}
TreeNode p = nodeMap.get(treeNode.getParentId());
if(p!=null){
p.add(treeNode);
}
}
return result;
}
/**
* 嵌套循环构建树 n*n
* @Author dong
* @Date 2023/11/20 下午 3:26
* @param treeNodes
* @param root
* @return java.util.List<T>
*/
public <T extends TreeNode> List<T> build(List<T> treeNodes, Object root) {
List<T> result = new ArrayList<>();
for (T treeNode : treeNodes) {
if (Objects.equals(root, treeNode.getParentId())) {
result.add(treeNode);
}
for (T it : treeNodes) {
if (Objects.equals(it.getParentId(), treeNode.getId())) {
treeNode.add(it);
}
}
}
return result;
}
/**
* 迭代构建树
* @Author dong
* @Date 2023/11/20 下午 3:25
* @param treeNodes
* @param root
* @return java.util.List<T>
*/
public <T extends TreeNode> List<T> buildByRecursive(List<T> treeNodes, Object root) {
List<T> result = new ArrayList<T>();
for (T treeNode : treeNodes) {
if (Objects.equals(root, treeNode.getParentId())) {
result.add(loadChildren(treeNode, treeNodes));
}
}
return result;
}
private <T extends TreeNode> T loadChildren(T treeNode, List<T> treeNodes) {
for (T it : treeNodes) {
if (treeNode.getId() == it.getParentId()) {
treeNode.add(loadChildren(it, treeNodes));
}
}
return treeNode;
}
}