java递归返回不确定层级的树状结构数据
- 前言
- 开始代码实现
- 总结:仰天大笑出门去,我辈岂是蓬蒿人
前言 有些业务返回的数据需要是树状类型的,但是也会有不确定层级到底有几层的树状,本篇讲解了不确定层级树状结构的递归实现原理,及实现
实体类的字段注释
/** 菜单ID */
private Long menuId;
/** 菜单名称 */
private String menuName;
/** 父菜单ID */
private Long parentId;
/** 子菜单 */
private List children = new ArrayList();
开始代码实现
- mapper层执行查询语句,无需处理,拿到菜单数据,也可根据业务做对应的筛选返回
SELECT
menu_id,
menu_name,
parent_id
FROM
sys_menu
- 这是serviceImpl层进行数据的处理
注意,这里可分为三个步骤
- 查询拿到的数据
- 创建用来返回的对象,通过stream的map算子取出所有菜单id
- 递归实现树状数据
/**
* @Description: [将查询的数据转为树结构列表返回]
*
* @param: [menus]
* @return: java.util.List
* @date: 2022/9/5 15:22
* @author: 杨永卓
*/
private List buildTree(List menus) {
//返回数据对象
List result = new ArrayList<>();
if(CollectionUtil.isEmpty(menus)) return result;
//获取所有菜单id
List tempList = menus.stream()
.map(e -> e.getMenuId())
.collect(Collectors.toList());
for (SysMenu menu : menus) {
//如果这个菜单的id没有父节点id就是顶级菜单,进入递归
if (!tempList.contains(menu.getParentId())) {
recursion(menus,menu);
result.add(menu);
}
}
return result;
}
- 封装的递归代码
/**
* @Description: [逐层调用,先从顶级菜单开始,一步一步的取出子菜单放入children里面]
*
* @param: [menus]
* @return: java.util.List
* @date: 2022/9/5 15:22
* @author: 杨永卓
*/
private void recursion(List menus, SysMenu menu) {
//拿到子菜单数据,放到children
List children = menus.stream()
.filter(e -> e.getParentId().longValue() == menu.getMenuId().longValue())
.collect(Collectors.toList());
menu.setChildren(children);
//循环,如果子菜单有子数据,就调用此方法递归查询,一直到没有子菜单数据为止
for (SysMenu child : children) {
int size = menus.stream()
.filter(e -> e.getParentId().longValue() == child.getMenuId().longValue())
.collect(Collectors.toList())
.size();
if (size > 0) {
recursion(menus, child);
}
}
}
总结:仰天大笑出门去,我辈岂是蓬蒿人
推荐阅读
- Mybatis|Mybatis——动态SQL
- #|java排序混乱的字符串字母和数字排序
- #|java自定义工具类编写规范
- #|AES解密报错,Input length must be multiple of 16 when decrypting with padded cipher
- #|Mybatis的if else妙用(Choose标签使用)
- 框架大集合|【MyBatis详解】——动态SQL解析与执行原理
- java|如何在 ACK 中使用 MSE Ingress
- Redis|Redis实现分布式锁
- spring|springAOP 通过注解实现 日志打印