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

yizhihongxing

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

相关文章

  • mysql中的多个字段最大最小值

    下面是MySQL中多个字段最大最小值的攻略。 问题描述 在MySQL中,如果有多个字段,需要找到这些字段中的最大/最小值,应该如何操作呢? 解决方案 方案一:使用多个子查询 使用多个子查询,分别查找每个字段的最大/最小值,然后再结合起来,这样就可以得到所有字段中的最大/最小值了。 示例: SELECT (SELECT MAX(column1) FROM ta…

    other 2023年6月25日
    00
  • 前端必备Nginx配置详解

    前端必备Nginx配置详解 这篇文章将向大家介绍如何在前端开发中使用Nginx服务器,包括安装、配置、常用命令等。 安装Nginx 安装Nginx很简单,可以通过包管理器直接安装: sudo apt-get update sudo apt-get install nginx 安装完后,可以通过下面的命令检查是否安装成功: nginx -v 基本配置 配置文件…

    other 2023年6月25日
    00
  • hmailserver邮件服务器搭建

    以下是关于“hMailServer邮件服务器搭建”的完整攻略,包括基本概念、步骤和两个示例。 基本概念 hMailServer是一款免费的邮件服务器软件,它在Windows操作系统上运行,并提供SMTP、POP3和IMAP等协议支持。使用hMailServer可以搭建自己的邮件服务器,便于管理和发送邮件。 步骤 以下是使用hMailServer搭建邮件服务器…

    other 2023年5月7日
    00
  • win10加密文件夹小锁如何去除?

    首先需要明确的是,如果你加密了一个文件夹,那么在该文件夹中的所有文件只有在输入正确的密码或使用正确的密钥之后才能访问。因此,如果你想去除加密文件夹中的小锁图标,就需要先解密该文件夹。 以下是去除win10加密文件夹小锁的完整攻略: 1.解密加密文件夹 首先,打开加密文件夹,右击文件夹并选择“属性”。 在属性窗口中,选择“高级”选项卡。 在高级属性窗口中,取消…

    other 2023年6月28日
    00
  • Go语言的结构体还能这么用?看这篇就够了

    让我来给你详细讲解一下“Go语言的结构体还能这么用?看这篇就够了”的完整攻略。 1. 简介 Go语言的结构体是一种自定义数据类型,它可以包含各种不同类型的数据,如数字、字符串、布尔值等。除此之外,结构体还可以嵌套、匿名等等,使其更加灵活多变。在本篇攻略中,我们将探讨结构体的一些高级用法,让你更好地掌握它。 2. 结构体的嵌入 2.1 基本用法 结构体的嵌入是…

    other 2023年6月27日
    00
  • Word加载项为灰色的无法使用的解决方法

    问题描述:在使用Word时,如果加载项(Add-ins)的选项为灰色且无法选择,那么意味着该加载项无法使用。这时候,我们需要找到解决方法。 解决方法:以下为具体步骤: Step 1: 首先,我们需要判断是否存在Word的启动冲突。 – 示例:Word的启动冲突可能是由于与其他Office程序(如Outlook、Excel等)冲突所致。如果出现这种情况,可以尝…

    other 2023年6月25日
    00
  • Android中TabLayout结合ViewPager实现页面切换

    下面我就为您详细讲解“Android中TabLayout结合ViewPager实现页面切换”的完整攻略。 1. 准备工作 在进行具体实现之前,我们需要进行一些准备工作: 添加相关依赖库,在build.gradle文件中加入以下依赖: groovy implementation ‘com.google.android.material:material:1.3…

    other 2023年6月26日
    00
  • JVM内存分配及String常用方法解析

    当然!下面是关于\”JVM内存分配及String常用方法解析\”的完整攻略: JVM内存分配及String常用方法解析 JVM内存分配 在Java中,JVM会自动管理内存分配。以下是JVM中常见的内存区域: 堆(Heap):用于存储对象实例和数组。堆内存由垃圾回收器自动管理,对象的创建和销毁都在堆中进行。 栈(Stack):用于存储局部变量和方法调用。栈内存…

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