前言
在树形结构的数据中,经常会有构建树、根据某节点向上生成树,根据某节点向下生成树的需求,这些都可以使用递归方法实现,递归方法这里不进行赘述,如有需要,请自行百度。个人觉得递归性能较差,可控性也不强,特此发表个博客记录一下,此博客是根据某节点向上生成树形结构,如果需要构建整棵树或都根据某个节点向下生成树,可以移步至我的另一篇博客附上链接:https://blog.csdn.net/qq_38516524/article/details/122046824
实现原理
以菜单为例,创建一个Map,key为菜单Id,value为菜单对象,重点为创建Map开始,之前的代码均为处理数据,可忽略,开始一个while循环,找到当前菜单的父级菜单,将当前菜单赋给父级菜单,然后将当前菜单的引用改为父级菜单,将parentId变更为父菜单的父菜单,当满足跳出条件后,返回的就是最终结果了。
实现代码
public AppMenuTree queryUp(String menuCode) {
// 获取数据
List<AppMenuWithBLOBs> menuList = getMenuList();
// 类型转换
List<AppMenuTree> menuTreeList = menuList.stream().map(menu -> {
AppMenuTree temMenu = new AppMenuTree();
BeanUtils.copyProperties(menu, temMenu);
return temMenu;
}).collect(Collectors.toList());
// 过滤目标
AppMenuTree appMenu = menuTreeList.stream().filter(menu -> menuCode.equalsIgnoreCase(menu.getMenuCode()))
.findFirst().orElse(new AppMenuTree());
// 创建Map,key为id
Map<Integer, AppMenuTree> menuMap = menuTreeList.stream()
.collect(Collectors.toMap(AppMenuTree::getAmeId, menu -> menu, (m1, m2) -> m2));
Integer parentId = appMenu.getParentId();
AppMenuTree resMenu = null;
// 设置循环次数,防止死循环
int count = 0;
while (true) {
// 跳出条件
if (parentId.equals(-1) || count > 10000) {
break;
}
resMenu = menuMap.get(parentId);
// 找到父级菜单,将当前菜单赋值给父菜单的子属性
resMenu.setChild(ListUtil.toList(appMenu));
appMenu = resMenu;
parentId = resMenu.getParentId();
count++;
}
return resMenu;
}
PS.跳出条件需要根据自己的情况设置,这里设置了一个变量来限制它的循环次数,防止死循环。
👍 欢迎前往博客主页查看更多内容
👍 如果觉得不错,期待您的点赞、收藏、评论、关注
👍 如有错误欢迎指正!