java构建树

先看看模拟的数据库的值(数据库名:company(公司))

可以根据parentId为0的数据为父节点,但是有些数据库根据不同的情况,设置了不同属性

level(等级1为顶点)idparentId(父公司Id)name(公司名)
110顶级节点A
120顶级节点B
231父节点是A
242父节点是B
252父节点是B
363父节点的ID是3

构建一棵树的步骤

1、首先获取所有的根节点(顶级节点),跟数据库的配置有关
2、根据每一个根节点,与所有节点集合(数据)进行判断,当前节点是否为其下的子节点。
3、若是,则递归调用构建树形;若不是,则表明该节点不属于其下子节点。
4、应继续循环判断节点父子关系,直到所有节点与根节点判断完毕。

   /**
     * 构造树(需要根据不同的情况变动)
     * @return
     */
    private List<TreeNode> constructionTree(List<Company> list) {
        // 全部数据(由查找的数据遍历得到)
        List<TreeNode> allList = new ArrayList<>();
        // 根节点的数据
        List<TreeNode> rootNodeList = new ArrayList<>();
        // 最终的树结构
        List<TreeNode> treeList = new ArrayList<>();
        // 获取根节点
        list.forEach(x -> {
            // 这里就是说根节点是级别为1的值
            if ("1".equals(x.getLevel())) {
                TreeNode treeNode = new TreeNode()
                        .setKey(x.getId())
                        .setId(x.getId())
                        .setTitle(x.getName())
                        .setParentId(x.getParentId());
                rootNodeList.add(treeNode);
            }
        });
        // 构造树结构,这里可以执行过滤操作,把list(List<Data>)过滤成我们需要的参数(allList)
        list.forEach(x->{
            TreeNode treeNode = new TreeNode()
                    .setKey(x.getId())
                    .setId(x.getId())
                    .setTitle(x.getName())
                    .setParentId(x.getParentId());
            allList.add(treeNode);
        });
        // 装配树干
        for (TreeNode treeRootNode : rootNodeList) {
            // 将顶级节点进行构建子树
            treeRootNode = buildChildTree(treeRootNode,allList);
            // 完成一个顶级节点所构建的树形,增加进来
            treeList.add(treeRootNode);
        }
        return treeList;
    }
    /**
     *  递归-----构建子树形结构
     *  @param  pNode 根节点(顶级节点)
     *  @param  treeList 全部数据
     *  @return 整棵树
     */
    public TreeNode buildChildTree(TreeNode pNode, List<TreeNode> treeList){
        List<TreeNode> childTree = new ArrayList<>();
        // nodeList:所有节点集合(所有数据)
        for (TreeNode treeNode : treeList) {
            // 判断当前节点的父节点ID是否等于根节点的ID,即当前节点为其下的子节点
            if (treeNode.getParentId().equals(pNode.getId())) {
                // 再递归进行判断当前节点的情况,调用自身方法
                childTree.add(buildChildTree(treeNode,treeList));
            }
        }
        // for循环结束,即节点下没有任何节点,树形构建结束,设置树结果
        pNode.setChildren(childTree);
        return pNode;
    }

TreeNode(树节点类)(用于封装转给前端),里面的值可以改动

/**
 *  TreeNode 树节点
 *
 *  @author ZPA
 *  @date 2023年10月23日
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class TreeNode {

    /** ID(前端需要对应公司的id) */
    private String key;

    /** 节点id */
    private String id;

    /** 父节点id:顶级节点为 0 */
    private String parentId;

    /** 节点名称(前端需要对应公司的name) */
    private String title;

    /** 子节点 */
    private List<TreeNode> children;
}

Company(公司类)

/**
 * 模拟公司
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Company {
    /**
     * 公司等级
     */
    private String level;
    /**
     * 公司ID
     */
    private String id;
    /**
     * 父公司ID
     */
    private String parentId;
    /**
     * 公司名字
     */
    private String name;

}

测试

public class TreeTest {
    @Test
    public void treeTest(){
        // 模拟测试数据(模拟数据库的值)
        List<Company> companyList = new ArrayList<>();
        companyList.add(new Company("1","1","0","顶级节点A"));
        companyList.add(new Company("1","2","0","顶级节点B"));
        companyList.add(new Company("2","3","1","父节点是A"));
        companyList.add(new Company("2","4","2","父节点是B"));
        companyList.add(new Company("2","5","2","父节点是B"));
        companyList.add(new Company("3","6","3","父节点的ID是3"));

        
        TreeTest test = new TreeTest();
        // 原查询结果转换树形结构
        List<TreeNode> treeNodes = test.constructionTree(companyList);
        System.out.println(treeNodes);

    }

    /**
     * 构造树(需要根据不同的情况变动)
     * @return
     */
    private List<TreeNode> constructionTree(List<Company> list) {
        // 全部数据(由查找的数据遍历得到)
        List<TreeNode> allList = new ArrayList<>();
        // 根节点的数据
        List<TreeNode> rootNodeList = new ArrayList<>();
        // 最终的树结构
        List<TreeNode> treeList = new ArrayList<>();
        // 获取根节点
        list.forEach(x -> {
            // 这里就是说根节点是级别为1的值
            if ("1".equals(x.getLevel())) {
                TreeNode treeNode = new TreeNode()
                        .setKey(x.getId())
                        .setId(x.getId())
                        .setTitle(x.getName())
                        .setParentId(x.getParentId());
                rootNodeList.add(treeNode);
            }
        });
        // 构造树结构,这里可以执行过滤操作,把list(List<Data>)过滤成我们需要的参数(allList)
        list.forEach(x->{
            TreeNode treeNode = new TreeNode()
                    .setKey(x.getId())
                    .setId(x.getId())
                    .setTitle(x.getName())
                    .setParentId(x.getParentId());
            allList.add(treeNode);
        });
        // 装配树干
        for (TreeNode treeRootNode : rootNodeList) {
            // 将顶级节点进行构建子树
            treeRootNode = buildChildTree(treeRootNode,allList);
            // 完成一个顶级节点所构建的树形,增加进来
            treeList.add(treeRootNode);
        }
        return treeList;
    }
    /**
     *  递归-----构建子树形结构
     *  @param  pNode 根节点(顶级节点)
     *  @param  treeList 全部数据
     *  @return 整棵树
     */
    public TreeNode buildChildTree(TreeNode pNode, List<TreeNode> treeList){
        List<TreeNode> childTree = new ArrayList<>();
        // nodeList:所有节点集合(所有数据)
        for (TreeNode treeNode : treeList) {
            // 判断当前节点的父节点ID是否等于根节点的ID,即当前节点为其下的子节点
            if (treeNode.getParentId().equals(pNode.getId())) {
                // 再递归进行判断当前节点的情况,调用自身方法
                childTree.add(buildChildTree(treeNode,treeList));
            }
        }
        // for循环结束,即节点下没有任何节点,树形构建结束,设置树结果
        pNode.setChildren(childTree);
        return pNode;
    }
}

结果打印

[
    {
        "children": [
            {
                "children": [
                    {
                        "children": [],
                        "id": "6",
                        "key": "6",
                        "parentId": "3",
                        "title": "父节点的ID是3"
                    }
                ],
                "id": "3",
                "key": "3",
                "parentId": "1",
                "title": "父节点是A"
            }
        ],
        "id": "1",
        "key": "1",
        "parentId": "0",
        "title": "顶级节点A"
    },
    {
        "children": [
            {
                "children": [],
                "id": "4",
                "key": "4",
                "parentId": "2",
                "title": "父节点是B"
            },
            {
                "children": [],
                "id": "5",
                "key": "5",
                "parentId": "2",
                "title": "父节点是B"
            }
        ],
        "id": "2",
        "key": "2",
        "parentId": "0",
        "title": "顶级节点B"
    }
]

参考博文:java树形结构添加层级