go to index

Spring boot树状数据工具类

read time 2 min read
Spring Boot tree 工具类

简介

在实际项目开发中,例如构造菜单或组织架构的数据时,经常会需要返回树状的层级数据。解决这个问题可以通过构造 SQL 语句或者递归来进行构造。本文推荐使用递归方式来构建树状数据。

数据模型

假设数据表使用 parentId 字段进行父子级关联。定义一个 VO 类来表示树节点:

java
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(description = "TreeVO")
public class TreeVO {

    @ApiModelProperty(value = "主键id")
    private long id;

    @ApiModelProperty(value = "父id")
    private long parentId;

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

工具类

构建树节点

通过递归方法构建树状结构:

java
import java.util.*;

public class TreeUtil {

    /**
     * 根据 pid 构建树节点
     */
    public static <T extends TreeVO> List<T> build(List<T> treeNodes, Integer pid) {
        List<T> treeList = new ArrayList<>();
        for (T treeNode : treeNodes) {
            if (pid.equals(treeNode.getParentId())) {
                treeList.add(findChildren(treeNodes, treeNode));
            }
        }
        return treeList;
    }

    /**
     * 查找子节点
     */
    private static <T extends TreeVO> T findChildren(List<T> treeNodes, T rootNode) {
        for (T treeNode : treeNodes) {
            if (rootNode.getId().equals(treeNode.getParentId())) {
                rootNode.getChildren().add(findChildren(treeNodes, treeNode));
            }
        }
        return rootNode;
    }

    /**
     * 构建树节点(无参版本)
     */
    public static <T extends TreeVO> List<T> build(List<T> treeNodes) {
        List<T> result = new ArrayList<>();
        // list 转 map
        Map<Long, T> nodeMap = new LinkedHashMap<>(treeNodes.size());
        for (T treeNode : treeNodes) {
            nodeMap.put(treeNode.getId(), treeNode);
        }

        for (T node : nodeMap.values()) {
            T parent = nodeMap.get(node.getParentId());
            if (parent != null && !node.getId().equals(parent.getId())) {
                parent.getChildren().add(node);
                continue;
            }
            result.add(node);
        }
        return result;
    }
}

使用示例

假设你有一个包含多个 TreeVO 对象的列表 treeNodes,你可以通过以下方式构建树状结构:

java
List<TreeVO> treeNodes = // 获取你的数据列表
List<TreeVO> tree = TreeUtil.build(treeNodes, 0); // 假设根节点的 parentId 为 0