JAVA递归生成树形菜单的实现过程

下面是详细讲解“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技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 中兴AXON天机7有哪四个版本 中兴AXON天机7各版本区别介绍

    中兴AXON天机7版本介绍攻略 中兴AXON天机7是一款备受关注的智能手机,共有四个版本。下面将详细介绍每个版本的区别。 1. 中兴AXON天机7标准版 处理器:搭载高性能的骁龙865处理器,提供出色的性能和流畅的操作体验。 内存和存储:配备8GB RAM和128GB内部存储空间,可满足大部分用户的需求。 摄像系统:后置主摄像头为6400万像素,支持光学防抖…

    other 2023年8月1日
    00
  • java核心技术卷1pdf

    Java核心技术卷1是Java开发者必备的一本书籍,它包含了Java编程的基础知识和高级技术。以下是获取Java核心技术卷1的PDF版本的攻略,包括两个示例说明。 步骤1:搜索并下载Java核心技术卷1的PDF版本 您可以在互联网上搜索Java核心技术卷1的PDF版本,并从可靠的网站下载它。以下是一些常用的网站: https://www.pdfdrive/ …

    other 2023年5月6日
    00
  • Linux系统的垃圾清理方法总结

    Linux系统的垃圾清理方法总结 什么是垃圾清理? 垃圾清理是指在Linux系统上清除没有用处或者不必要的文件和目录的操作,通过垃圾清理操作能够释放存储空间并提供系统的整体性能。 垃圾清理方法 1. apt-get autoclean 使用 apt-get autoclean 命令可以清理废弃的包文件(不包括当前安装软件所依赖的文件)。 sudo apt-g…

    other 2023年6月27日
    00
  • iPhone微信内存占用多怎么办 微信占用过多内存的解决方法

    iPhone微信内存占用多的解决方法 微信是一款功能强大的社交应用,但有时候它可能会占用过多的内存,导致iPhone运行缓慢。下面是解决iPhone微信内存占用过多的一些方法和示例说明。 方法一:清理微信缓存 微信缓存是存储在iPhone上的临时文件,随着时间的推移会逐渐增加,占用大量的内存。清理微信缓存可以帮助释放内存空间,提高iPhone的性能。 打开微…

    other 2023年8月1日
    00
  • 关于VUE的编译作用域及slot作用域插槽问题

    关于VUE的编译作用域及slot作用域插槽问题攻略 在Vue中,编译作用域和slot作用域插槽是两个重要的概念。编译作用域指的是模板中可以访问的变量,而slot作用域插槽则允许父组件向子组件传递数据。 编译作用域 编译作用域是指在Vue模板中可以直接访问的变量。在模板中,可以使用双大括号语法({{ }})来插入变量。这些变量可以是Vue实例中的数据属性,也可…

    other 2023年8月20日
    00
  • mysql无法远程连接的解决方法

    当然,我很乐意为您提供有关“MySQL无法远程连接的解决方法”的完整攻略。以下是详细的步骤和两个示例: 1 MySQL无法远程连接的解决方法 如果您无法从远程计算机连接到MySQL服务器,则可能需要进行以下设置: 1.1 修改MySQL配置文件 在MySQL服务器上,您需要修改MySQL配置文件以允许远程连接。以下是修改MySQL配置文件的示例: sudo …

    other 2023年5月6日
    00
  • 详解Nuxt内导航栏的两种实现方式

    详解Nuxt内导航栏的两种实现方式 Nuxt.js 是一个基于 Vue.js 的通用应用框架,它提供了一种简单而强大的方式来构建服务器渲染的应用程序。在 Nuxt.js 中,实现导航栏有两种常见的方式,下面将详细介绍这两种方式,并提供示例说明。 1. 使用 Nuxt.js 的内置导航栏组件 Nuxt.js 提供了一个内置的导航栏组件 nuxt-link,它可…

    other 2023年7月28日
    00
  • 【abp框架系列学习】模块系统(4)之插件示例开发

    ABP框架系列学习:模块系统(4)之插件示例开发 ABP框架中的插件是一种可拔的模块,可以在应用程序运行时动态加载和卸载。本攻略将介绍如何使用ABP框架开发插件例,包括创建插件项目、实现插件接口、注册插件等。 创建插件项目 使用ABP框架创建插件项目的骤如下: 打开Visual Studio,创建一个新的ABP解决方案。 在解决方案中,右键单击“解方案”节点…

    other 2023年5月7日
    00
合作推广
合作推广
分享本页
返回顶部