在实际开发中,我们经常会开发菜单,树形结构,数据库一般就使用父id来表示,为了降低数据库的查询压力,我们可以使用Java8中的Stream流一次性把数据查出来,然后通过流式处理,我们一起来看看,代码实现为了实现简单,就模拟查看数据库所有数据到List里面。
为了实现这种效果:
下面就使用的一个简单的例子进行演示:
实体类: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;
}
}
使用递归构建树形结构
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;
}
}
输出结果:
输出的JSON格式的结果你可以直接复制进行测试查看。