一、第一种方法
1、数据库结构,一张表。
roleCode为对应的id,superiorUnit为每条数据的父类ID、
2、bean结构
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RoleBean implements Serializable {
private String roleCode;
private String roleName;
private String superiorUnit;//父类id parentId最好
private String roleDesc;
private int enable;
private List<RoleBean> childs;
}
第一种方法最简单,直接套里面
List<Tagl25TacAccount> collect = tagl25TacAccounts.stream().filter(menu -> Objects.isNull(menu.getParentSid())).peek(
//设置子节点信息
menu -> menu.setChildList(getChildrenList(menu, tagl25TacAccounts))
).collect(Collectors.toList());
System.out.println(JSON.toJSONString(collect));
private List<Tagl25TacAccount> getChildrenList(Tagl25TacAccount root, List<Tagl25TacAccount> menus) {
List<Tagl25TacAccount> list = menus.stream().filter(menu ->
//筛选出下一节点元素
Objects.equals(menu.getParentSid(), root.getSysId())).map(menu -> {
//递归set子节点
menu.setChildList(this.getChildrenList(menu, menus));
return menu;
}).collect(Collectors.toList());
return list;
}
3、代码 、相当于工具类调用
第二种方法
public class treeUtil {
private List<RoleBean> rootList; // 根节点对象存放到这里
private List<RoleBean> bodyList; // 其他节点存放到这里,可以包含根节点
public treeUtil(List<RoleBean> rootList, List<RoleBean> bodyList) {
this.rootList = rootList;
this.bodyList = bodyList;
}
public List<RoleBean> getTree() { // 调用的方法入口
if (bodyList != null && !bodyList.isEmpty()) {
// 声明一个map,用来过滤已操作过的数据
Map<String, String> map = new HashMap<>();
rootList.forEach(beanTree -> getChild(beanTree, map));
return rootList;
}
return null;
}
public void getChild(RoleBean beanTree, Map<String, String> map) {
List<RoleBean> childList = Lists.newArrayList();
//map.containsKey()判断map中key是否存在,存在返回true 不存在返回false,!相反
bodyList.stream().filter(c -> !map.containsKey(c.getId())).filter(c -> Objects.nonNull(c.getParentId()) && c.getParentId().equals(beanTree.getId()))
.forEach(c -> {
map.put(c.getId(), c.getParentId());
getChild(c, map);
childList.add(c);
});
beanTree.setChilds(childList);
}
}
4、测试调用
/**
*roleBeanList 为查出来的数据
*/
public List<RoleBean> getRoleTree(List<RoleBean> roleBeanList) {
List<RoleBean> baseLists = new ArrayList<>();
// 总菜单,出一级菜单,一级菜单没有父id
List<RoleBean> rootList = tagl25TacAccounts.stream().filter(v -> Objects.isNull(v.getParentId())).collect(Collectors.toList());
treeUtil utils = new treeUtil(rootList , roleBeanList);
List<RoleBean> result = utils.getTree();
return result;
测试结果截图
二、第三种方法
1、数据库结构与第一种数据库结构一摸一样
2、bean类结构
在这@Data
@AllArgsConstructor
@NoArgsConstructor
public class RoleBean implements Serializable {
private String roleCode;
private String roleName;
private String superiorUnit;//父类id parentId最好
private String roleDesc;
private int enable;
private List<RoleBean> childs;
public RoleBean(String id, String shortName, String parentId) {
this.id = id;
this.shortName = shortName;
this.parentId = parentId;
}
}
3、代码
/*
*roleAllList 为查询数据库表中的所有数据
*/
@Override
public List<RoleBean> newRoleTree(List<RoleBean> roleAllList){
List<RoleBean> baseLists = new ArrayList<>();
// 总菜单,出一级菜单,一级菜单没有父id
for (RoleBean e : roleAllList) {
if (e.getParentId() == null||"".equals(e.getParentId())) {
baseLists.add(e);
}
}
// 遍历一级菜单
for (RoleBean e : baseLists) {
// 将子元素 set进一级菜单里面 getChild()方法在下方
e.setChilds(getChild(e.getId(), roleAllList));
}
return baseLists;
}
/**
* 获取子节点
*
* @param pid
* @param roleBeanList
* @return
*/
private List<RoleBean> getChild(String pid, List<RoleBean> roleBeanList) {
List<RoleBean> childs = new ArrayList<>();
for (RoleBean e : roleBeanList) {
if (e.getParentId() != null ||!"".equals(e.getParentId())) {
if (e.getParentId().equals(pid)) {
// 子菜单的下级菜单
childs.add(e);
}
}
}
// 把子菜单的子菜单再循环一遍
for (RoleBean e : childs) {
// 继续添加子元素
e.setChilds(getChild(e.getId(), roleBeanList));
}
//停下来的条件,如果 没有子元素了,则停下来
if (childs.size() == 0) {
return null;
}
return childs;
}
4、测试
以上数据是从数据库查出,如果想测试可以单纯的new 几个数据就可以测试,对应的也应该有父类id,对应的有子类对应着父类id