Use Stream to traverse the tree structure in Java 8

        In actual development, we often develop menus and tree structures, and the database is generally represented by the parent id. In order to reduce the query pressure on the database, we can use the Stream stream in Java8 to check the data at one time, and then pass the stream Processing, let's take a look together. In order to achieve simple code implementation, we simulate to view all the data in the database into the List.

        To achieve this effect:

The following is a simple example of use to demonstrate:

Entity class: Departments.java

@Data
@Builder
public class Departments {
    /**
     * id
     */
    public Integer id;
    /**
     * 名称
     */
    public String name;
    /**
     * 父id ,根节点为0
     */
    public Integer parentId;
    /**
     * 子节点信息
     */
    public List<Departments> childList;


    public Departments(Integer id, String name, Integer parentId) {
        this.id = id;
        this.name = name;
        this.parentId = parentId;
    }

    public Departments(Integer id, String name, Integer parentId, List<Departments> childList) {
        this.id = id;
        this.name = name;
        this.parentId = parentId;
        this.childList = childList;
    }
}

Build a tree structure using recursion

public class DepartmentsTreeTest {

    @Test
    public void testtree() {
        // 模拟从数据库查询出来的菜单数据
        List<Departments> departments = Arrays.asList(
                new Departments(1, "总行", 0),
                new Departments(2, "分行", 1),
                new Departments(3, "攀枝花分行", 2),
                new Departments(4, "成都分行", 2),
                new Departments(5, "凉山分行", 2),
                new Departments(6, "支行", 1),
                new Departments(7, "绵阳支行", 6),
                new Departments(8, "德阳支行", 6),
                new Departments(9, "绵阳支行街道", 7),
                new Departments(10, "德阳支行街道", 7),
                new Departments(11, "子公司", 1),
                new Departments(12, "我是子公司", 11)
        );
        // 获取部门菜单信息
        // 通过filter()方法筛选出所有部门菜单项。部门的特征是parentId为0,即没有父节点。这些部门菜单项的列表被称为collect
        List<Departments> collect = departments.stream().filter(m -> m.getParentId() == 0)
                // 对于每个部门菜单项,我们使用map()方法来递归所有部门地获取其所有子菜单项,并将这些子菜单项设置为部门菜单项的childList属性。
                .map((m) -> {
                    m.setChildList(getChildrens(m, departments));
                    return m;
                }
        ).collect(Collectors.toList());
        System.out.println("-------转json输出结果-------");
        System.out.println(JSON.toJSON(collect));
    }

    /**
     * 递归查询部门
     * @param root 部门
     * @param all  所有节点
     * @return 包含所有部门的列表
     */
    private List<Departments> getChildrens(Departments root, List<Departments> all) {
        // 过滤出所有与部门的id相匹配的部门
        List<Departments> children = all.stream().filter(m -> {
            // 当所有节点中的parentid与部门的id一致时,表示为部门的部门
            return Objects.equals(m.getParentId(), root.getId());
        }).map(
                (m) -> {
                    // 递归查询该部门的部门
                    m.setChildList(getChildrens(m, all));
                    return m;
                }
        ).collect(Collectors.toList());
        return children;
    }

}

Output result:

        You can directly copy the output results in JSON format for testing and viewing.

 

おすすめ

転載: blog.csdn.net/m0_64210833/article/details/132103491