下面是详细讲解“JAVA递归生成树形菜单的实现过程”的完整攻略。
1. 菜单结构的定义
在使用递归生成树形菜单之前,需要先定义好菜单结构。这里我们定义一个Menu
类来代表菜单项,包含以下属性:
public class Menu {
private Long id;
private String name;
private Long parentId;
private List<Menu> children = new ArrayList<>();
// 省略 getter 和 setter 方法
}
其中,id
为菜单项的唯一标识符,name
为菜单项名称,parentId
为当前菜单项的父级菜单项id,children
为当前菜单项的子菜单项列表。
2. 数据查询
在递归生成树形菜单之前,需要先从数据源中查询到所有的菜单项数据。这里我们以MySQL数据库为例,查询语句如下:
SELECT id, name, parent_id FROM menu
查询结果为一个包含所有菜单项的列表(如果使用Mybatis等ORM框架可以直接将查询结果映射到Menu
类中),我们将其保存在一个List<Menu>
中。
3. 递归生成树形菜单
递归生成树形菜单的过程主要由两个步骤组成:
3.1 构建菜单项之间的父子关系
在将查询结果映射到Menu
类之后,我们需要构建菜单项之间的父子关系。这里我们可以通过遍历菜单项列表,通过parentId
属性来找到当前菜单项的父级菜单项,并将其添加到父级菜单项的子菜单项列表中,最后构建出一棵完整的菜单树。示例如下:
public static List<Menu> buildMenuTree(List<Menu> menuList) {
Map<Long, Menu> menuMap = new HashMap<>();
List<Menu> rootMenuList = new ArrayList<>();
// 将所有菜单项放入map中便于查找
for (Menu menu : menuList) {
menuMap.put(menu.getId(), menu);
}
// 将所有菜单项之间的父子关系构建出来
for (Menu menu : menuList) {
Long parentId = menu.getParentId();
if (parentId == null) {
// 父级菜单项为null表示当前菜单项为根节点
rootMenuList.add(menu);
} else {
Menu parentMenu = menuMap.get(parentId);
if (parentMenu != null) {
parentMenu.getChildren().add(menu);
}
}
}
return rootMenuList;
}
该方法接收一个包含所有菜单项的列表(即查询结果),返回生成的完整菜单树的根节点列表。
3.2 递归生成树形菜单
在得到菜单项之间的父子关系之后,我们通过递归遍历菜单树,生成树形菜单。示例如下:
public static void generateMenuTree(List<Menu> menuList, StringBuilder sb) {
sb.append("<ul>");
for (Menu menu : menuList) {
sb.append("<li>").append(menu.getName());
if (!menu.getChildren().isEmpty()) {
generateMenuTree(menu.getChildren(), sb);
}
sb.append("</li>");
}
sb.append("</ul>");
}
该方法接收一个菜单项列表以及一个StringBuilder
对象用于拼接菜单项HTML代码。递归地遍历菜单项列表,如果当前菜单项有子菜单项,则再次调用generateMenuTree
方法处理子菜单项,最后将生成的HTML代码添加到StringBuilder
中。
4. 示例说明
下面我们使用两个示例来说明如何使用递归生成树形菜单。
4.1 示例1
假设我们有以下菜单项:
id | name | parentId |
---|---|---|
1 | 系统管理 | null |
2 | 用户管理 | 1 |
3 | 角色管理 | 1 |
4 | 权限管理 | 1 |
5 | 用户添加 | 2 |
6 | 用户删除 | 2 |
7 | 角色添加 | 3 |
8 | 角色删除 | 3 |
9 | 权限设置 | 4 |
10 | 权限删除 | 4 |
我们可以先将其查询出来,放到一个List<Menu>
中,然后调用buildMenuTree
方法构建出菜单树的父子关系,最后调用generateMenuTree
方法递归生成HTML代码。示例如下:
List<Menu> menuList = queryMenuListFromDatabase();
List<Menu> rootMenuList = buildMenuTree(menuList);
StringBuilder sb = new StringBuilder();
generateMenuTree(rootMenuList, sb);
System.out.println(sb.toString());
输出的HTML代码如下:
<ul>
<li>系统管理
<ul>
<li>用户管理
<ul>
<li>用户添加</li>
<li>用户删除</li>
</ul>
</li>
<li>角色管理
<ul>
<li>角色添加</li>
<li>角色删除</li>
</ul>
</li>
<li>权限管理
<ul>
<li>权限设置</li>
<li>权限删除</li>
</ul>
</li>
</ul>
</li>
</ul>
4.2 示例2
假设我们有以下菜单项:
id | name | parentId |
---|---|---|
1 | 一级菜单1 | null |
2 | 一级菜单2 | null |
3 | 二级菜单1 | 1 |
4 | 二级菜单2 | 1 |
5 | 二级菜单3 | 2 |
6 | 三级菜单1 | 3 |
7 | 三级菜单2 | 4 |
8 | 四级菜单1 | 6 |
我们可以先将其查询出来,放到一个List<Menu>
中,然后调用buildMenuTree
方法构建出菜单树的父子关系,最后调用generateMenuTree
方法递归生成HTML代码。示例如下:
List<Menu> menuList = queryMenuListFromDatabase();
List<Menu> rootMenuList = buildMenuTree(menuList);
StringBuilder sb = new StringBuilder();
generateMenuTree(rootMenuList, sb);
System.out.println(sb.toString());
输出的HTML代码如下:
<ul>
<li>一级菜单1
<ul>
<li>二级菜单1
<ul>
<li>三级菜单1
<ul>
<li>四级菜单1</li>
</ul>
</li>
</ul>
</li>
<li>二级菜单2
<ul>
<li>三级菜单2</li>
</ul>
</li>
</ul>
</li>
<li>一级菜单2
<ul>
<li>二级菜单3</li>
</ul>
</li>
</ul>
至此,我们就完成了使用递归生成树形菜单的实现过程。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JAVA递归生成树形菜单的实现过程 - Python技术站