当前位置:网站首页>使用递归形成多级目录树结构,附带可能是全网最详细注释。
使用递归形成多级目录树结构,附带可能是全网最详细注释。
2022-06-23 22:26:00 【XuDream】
使用场景
在开发实现用户的职位、职务列表展示,后台管理页面用户的菜单目录展示。
一、效果展示
1. 数据库结构:
例如:电子产品/笔记本电脑/联想笔记本 生成一个三级目录
2. 数据处理返回:
{
"code": 200,
"msg": "操作成功",
"data": [
{
"id": "1",
"name": "电子产品",
"parentId": "0",
"type": 1,
"childList": [
{
"id": "5",
"name": "笔记本电脑",
"parentId": "1",
"type": 2,
"childList": [
{
"id": "21",
"name": "联想笔记本",
"parentId": "5",
"type": 3,
"childList": []
},
{
"id": "22",
"name": "外星人笔记本",
"parentId": "5",
"type": 3,
"childList": []
},
{
"id": "23",
"name": "戴尔笔记本",
"parentId": "5",
"type": 3,
"childList": []
}
]
},
{
"id": "6",
"name": "手机",
"parentId": "1",
"type": 2,
"childList": [
{
"id": "24",
"name": "苹果手机",
"parentId": "6",
"type": 3,
"childList": []
},
{
"id": "25",
"name": "菠萝手机",
"parentId": "6",
"type": 3,
"childList": []
}
]
},
{
"id": "7",
"name": "耳机",
"parentId": "1",
"type": 2,
"childList": []
},
{
"id": "8",
"name": "电子烟",
"parentId": "1",
"type": 2,
"childList": []
}
]
},
{
"id": "2",
"name": "生活用品",
"parentId": "0",
"type": 1,
"childList": [
{
"id": "10",
"name": "椅子",
"parentId": "2",
"type": 2,
"childList": []
},
{
"id": "11",
"name": "床",
"parentId": "2",
"type": 2,
"childList": []
},
{
"id": "19",
"name": "牙膏",
"parentId": "2",
"type": 2,
"childList": []
},
{
"id": "20",
"name": "牙刷",
"parentId": "2",
"type": 2,
"childList": []
},
{
"id": "9",
"name": "桌子",
"parentId": "2",
"type": 2,
"childList": []
}
]
},
{
"id": "3",
"name": "卫生用品",
"parentId": "0",
"type": 1,
"childList": [
{
"id": "12",
"name": "卫生纸",
"parentId": "3",
"type": 2,
"childList": []
},
{
"id": "13",
"name": "湿巾",
"parentId": "3",
"type": 2,
"childList": []
}
]
},
{
"id": "4",
"name": "学习用品",
"parentId": "0",
"type": 1,
"childList": [
{
"id": "14",
"name": "电子书",
"parentId": "4",
"type": 2,
"childList": []
},
{
"id": "15",
"name": "听力光盘",
"parentId": "4",
"type": 2,
"childList": []
},
{
"id": "16",
"name": "实体书",
"parentId": "4",
"type": 2,
"childList": []
},
{
"id": "17",
"name": "钢笔",
"parentId": "4",
"type": 2,
"childList": []
},
{
"id": "18",
"name": "笔记本子",
"parentId": "4",
"type": 2,
"childList": []
}
]
}
]
}
二、实现思路
- 获取所有的分类。
- 获取所有分类的id集合。使用stream()实现,stream使用教程
- 获取一级分类信息。同样使用stream()实现。
- 循环一级分类,在循环中将一级分类添加子分类,并且将一级分类加入返回的树结构中(备注:不加入返回的树结构中也行,直接返回步骤3的分类信息一样)。
- 重点是步骤4中将一级分类添加子分类,并且子分类在添加子子分类,子子分类再添加子子子分类··········等等,实现过程使用递归即可。
- 步骤5的实现过程:写一个递归方法,往当前节点添加子节点,首先获取当前节点的字节点集合,然后把这个集合放入到当前节点子节点属性中,接着再次调用当前递归的方法,把刚获取到的子节点当成新当前节点,获取新当前节点的新子节点,注意再次调用当前递归的方法,把刚获取到的子节点当成新当前节点之前首先判断新当前节点有没有子节点(判断方法:获取当前节点的字节点数组,根据数组的size()>0?判断是否有子节点),如果没有就不用递归。
- 总结:1-4是数据准备,5-6是实现递归(当前节点添加子节点的递归)。
三、代码展示
1. 主要思路代码
@GetMapping("/list")
public Result list() {
//所有的分类
List<Category> categoryList = categoryService.list();
//所有分类id集合
List<String> idList = categoryList.stream().map(Category::getId).collect(Collectors.toList());
//返回的树分类结果
List<Category> treeCategory = new ArrayList<>();
//一级分类目录
List<Category> categories = categoryList.stream().filter(category -> !idList.contains(category.getParentId())).collect(Collectors.toList());
//循环当前一级分类目录
for (Category category : categories) {
//给当前分类节点 添加 子分类节点
addChild(categoryList,category);
//当前分类添加完子节点分类之后,添加到返回的树结构中
treeCategory.add(category);
}
//把返回的树结构返回
return Result.success(categories);
}
/** * 给当前分类节点 添加 子分类节点 * @param categoryList 所有的分类 * @param category 当前分类节点 */
public void addChild( List<Category> categoryList,Category category){
//循环所有的分类,获取当前节点的所有子节点
List<Category> categoryListChild = categoryList.stream().filter(category1 -> category1.getParentId().equals(category.getId())).collect(Collectors.toList());
//把当前分类的子节点添加到当前分类
category.setChildList(categoryListChild);
//再次调用本方法,把当前节点的子节点当成当前节点,继续添加子节点,备注:这样会造成一直循环
categoryListChild.forEach(category1 -> {
//添加一步,判断当前节点是否有子节点,没有就不循环递归
//if ()
addChild(categoryList,category1);
});
}
/** * 判断当前节点 是否存在 子节点 * @param categoryList 所有的分类 * @param category 当前节点 */
public boolean haveChild( List<Category> categoryList,Category category){
//获取当前节点的子节点
List<Category> categoryListChild = categoryList.stream().filter(category1 -> category1.getParentId().equals(category.getId())).collect(Collectors.toList());
//子节点大于0则存在,否则不存在
return categoryListChild.size()>0?true:false;
}
2. 实体类代码展示
备注:实体类代码中一定要有一个子节点数组。实体类对用最上面的实体类图片
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class Category implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.ID_WORKER_STR)
private String id;
/** * 类别名称 */
private String name;
/** * 上级id */
private String parentId;
/** * 分类级别 */
private Integer type;
/** * 子节点数组 */
@TableField(exist = false)
private List<Category> childList;
}
边栏推荐
- Android 3年外包工面试笔记,有机会还是要去大厂学习提升,作为一个Android程序员
- Shutter control layout
- Learn PWN from CTF wiki - ret2text
- What is medical treatment? AI medical concept analysis AI
- [technical grass planting] Tencent Yunhao wool (consumption) record on the double 11
- [digital signal] spectrum refinement based on MATLAB analog window function [including Matlab source code 1906]
- . Net
- Complete collection of development environment configuration -- Visual Studio 2022 installation
- How much business do you need to know to do data analysis
- Salesforce batch apex batch processing (V) asyncapexjob intelligence
猜你喜欢

Interview notes for Android outsourcing workers for 3 years. I still need to go to a large factory to learn and improve. As an Android programmer

Tiktok practice ~ one click registration and login process of mobile phone number and password (restrict mobile terminal login)

1. < tag dynamic programming and path combination problem > lt.62 Different paths + lt.63 Different paths II

Save: software analysis, verification and test platform

C语言:结构体数组实现找出最低分学生记录

逆向工具IDA、GDB使用

985本3Android程序员40天拿下阿里P6口头offer,面试成功后整理了这些面试思路

What is medical treatment? AI medical concept analysis AI

WPF效果之Expander+ListBox

CPU取指到发出控制、微程序控制原理详细过程
随机推荐
Interview notes for Android outsourcing workers for 3 years. You still need to go to a large factory to learn and improve when you have the opportunity. Interview questions for Android Development Int
Complete collection of development environment configuration -- Visual Studio 2022 installation
Android - basics you need to know about JNI development, interview questions for Android engineers
Andorid development art exploration notes (2), cross platform applet development framework
== 和 equals 的区别是什么?
Go language core 36 lectures (go language practice and application 11) -- learning notes
What should I pay attention to in the interview of artificial intelligence technology?
What is the difference between concurrency and parallelism?
Wechat applet picture verification code display
Android AIDL:跨进程调用Service (AIDL Service),kotlininvoke函数
迷茫的测试/开发程序员,不同人有着不同的故事、有着不同的迷茫......
js 语言 精度问题
Dependency Inversion Principle
MySQL architecture (basic)
What is the future development of palmprint recognition technology?
Learn PWN from CTF wiki - ret2text
被同事坑到周末加班, 没见过把Redis用成这个鬼样子的。。。
Android - JNI 开发你所需要知道的基础,Android工程师面试题
Dot and cross product
I was cheated by my colleagues to work overtime on weekends. I haven't seen redis used like this...