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日

相关文章

  • package.json的所有配置项及其用法 你都熟悉么

    package.json的所有配置项及其用法 在JavaScript项目中,package.json是一个重要的配置文件。它除了记录项目的依赖、开发依赖之外,还有许多其他的配置项。下面我们将介绍package.json的所有配置项及其用法。 name name表示项目的名称。它是一个必填项,而且必须是小写字母,可以包含连字符和下划线。 { "nam…

    其他 2023年3月28日
    00
  • Android 软键盘弹出时把原来布局顶上去的解决方法

    在 Android 开发中,当软键盘弹出时,可能会导致原来页面的布局被顶上去,影响用户体验。因此,需要进行一些解决措施,以确保页面布局不会被软键盘覆盖。下面是一些解决方法的详细讲解。 1. 在 Manifest 文件中设置 Activity 的属性 在 Manifest 文件中,可以为 Activity 设置属性,以控制页面在软键盘弹出时的表现形式。以下是一…

    other 2023年6月27日
    00
  • 【Centos】桌面安装

    CentOS桌面安装的完整攻略 CentOS是一款基于Linux的操作系统,它是一款免费、开源的操作系统,广泛应用于服务器和桌面环境。在本文中,我们将详细介绍CentOS桌面安装的完整攻略,并提供两个示例说明。 步骤一:下载CentOS镜像文件 首先,我们需要从CentOS官网下载CentOS镜像文件。在下载页面中,我们可以选择不同的版本和桌面环境。选择适合…

    other 2023年5月5日
    00
  • MySQL5.7免安装版配置图文教程

    下面是详细的MySQL5.7免安装版配置攻略: 准备工作 下载MySQL5.7免安装版的压缩包,并解压到指定目录下; 加入MySQL的bin目录到系统的环境变量PATH中; 创建MySQL数据目录,并授权给MySQL用户。 配置MySQL 创建my.ini配置文件,内容如下: [mysqld] basedir=C:/mysql-5.7.31-winx64 d…

    other 2023年6月27日
    00
  • 什么时候应该在java中使用intstream.range?

    当我们需要生成一系列连续的整数时,可以使用Java 8中的IntStream.range()方法。以下是关于什么时候应该在Java中使用IntStream.range()的完整攻略: 1.Stream.range()的概念 IntStream.range()是Java 8中的一个方法,用于生成一系列连续的整数。该方法接受两参数,分别是起始值和结束值(不包括结…

    other 2023年5月7日
    00
  • html之table标签

    HTML之table标签 在网页开发中,table标签是常用的一种标签,通常用于展示表格数据。本文将介绍table标签及其常见属性的用法。 table标签基本结构 table标签用于定义表格,可以包含多个tr(table row)标签,每个tr标签可以包含多个td(table data)标签。以下是table标签的基本结构: <table> &l…

    其他 2023年3月28日
    00
  • 从C语言过渡到C++之基本变化

    从C语言过渡到C++需要理解两条基本变化:面向对象编程和类的概念。 面向对象编程 C++是一种面向对象编程语言,C语言则不是。面向对象编程将对象作为程序的基本单元,程序员利用面向对象编程语言构造出对象模型,运用特定的方法在对象之间传递消息和调用方法。对象的属性和方法封装在类中,类可以看作是对对象的模板定义。C++提供类的概念,而C语言则需要程序员自行实现一些…

    other 2023年6月26日
    00
  • sql语句把字段中的某个字符去掉

    下面是“SQL语句把字段中的某个字符去掉的完整攻略”,包括去掉字符的方法和两个示例说明。 去掉字符的方法 在SQL语句中,可以使用REPLACE函数来去掉字段中的某个字符。REPLACE函数的语法如下: REPLACE(string, old_substring, new_substring) 其中,string是要进行替换的字符串,old_substrin…

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