当前位置: 首页 > news >正文

三种常见的菜单路由封装方式详解

方式一:双重循环构建两级菜单

这种方式通过两层 for 循环分别处理父菜单和子菜单,实现相对直观简单。

private List<MenuRouterVO> getMenuRouterVOList(List<MenuEntity> menulist) {List<MenuRouterVO> menuRouterVOList = new ArrayList<>();// 遍历所有菜单,筛选顶级菜单(parentId=0)for (MenuEntity menu : menulist) {if (menu.getParentId() == 0) {MenuRouterVO menuRouterVO = new MenuRouterVO();BeanUtils.copyProperties(menu, menuRouterVO);// 设置meta信息MetaVo metaVo = new MetaVo();metaVo.setTitle(menu.getName());metaVo.setIcon(menu.getIcon());menuRouterVO.setMeta(metaVo);// 查找当前顶级菜单的子菜单List<ChildrenMenuRouterVO> children = new ArrayList<>();for (MenuEntity child : menulist) {if (child.getParentId() == menu.getMenuId()) {ChildrenMenuRouterVO childMenuRouterVO = new ChildrenMenuRouterVO();BeanUtils.copyProperties(child, childMenuRouterVO);MetaVo childMetaVo = new MetaVo();childMetaVo.setTitle(child.getName());childMetaVo.setIcon(child.getIcon());childMenuRouterVO.setMeta(childMetaVo);children.add(childMenuRouterVO);}}menuRouterVO.setChildren(children);menuRouterVOList.add(menuRouterVO);}}return menuRouterVOList;
}

特点分析

  • 实现简单直接,容易理解
  • 仅支持两级菜单结构,不支持多级嵌套
  • 时间复杂度为 O (n²),数据量大时效率较低
  • 适合简单的两级菜单场景

方式二:递归构建多级菜单树

通过递归调用的方式,可以灵活构建任意层级的菜单结构。

@Override
public Map MenuList() {Map<String, Object> result = new HashMap<>();// 查询所有菜单项List<MenuEntity> AllMenuEntity = menuMapper.selectList(null);// 筛选顶级菜单(parentId=0)并构建菜单树List<MenuVO> TopMenu = new ArrayList<>();for (MenuEntity menuEntity : AllMenuEntity) {if (menuEntity.getParentId().equals(0)) {MenuVO menuVO = new MenuVO();BeanUtils.copyProperties(menuEntity,menuVO);menuVO.setId(menuEntity.getMenuId());// 递归构建当前顶级菜单的子菜单层级menuVO.setChildren(buildChildMenu(menuEntity.getMenuId(),AllMenuEntity));TopMenu.add(menuVO);}}result.put("data", TopMenu);return result;
}// 递归构建子菜单树
private List<ChildMenuVO> buildChildMenu(Integer parentId, List<MenuEntity> allMenuEntity) {List<ChildMenuVO> childMenuList = new ArrayList<>();// 查找当前父菜单ID对应的所有子菜单for (MenuEntity menuEntity : allMenuEntity) {if(menuEntity.getParentId().equals(parentId)){ChildMenuVO childMenuVO = new ChildMenuVO();BeanUtils.copyProperties(menuEntity,childMenuVO);childMenuVO.setId(menuEntity.getMenuId());// 递归获取子菜单的子菜单(多级菜单)List<ChildMenuVO> grandChildren = buildChildMenu(menuEntity.getMenuId(), allMenuEntity);childMenuVO.setChildren(grandChildren);childMenuList.add(childMenuVO);}}return childMenuList;
}

特点分析

  • 支持无限层级的菜单结构
  • 代码逻辑清晰,易于维护
  • 时间复杂度较高,每次递归都需要遍历整个菜单列表
  • 适合需要多级嵌套的复杂菜单场景

方式三:HashMap 映射构建菜单树

利用 HashMap 的 O (1) 查找特性,先构建映射关系再组装菜单树,提高效率。

@Override
public List<MenuRouterVO> getMenuRoleByUser(Integer userId) {List<Menu> menuList = menuMapper.getMenuRouterByUserId(userId);// 定义所需对象MenuRouterVO menuRouterVO;ChildrenMenuRouterVO childrenMenuRouterVO;MetaVO metaVO;// 用Map存储菜单ID与菜单对象的映射关系Map<Integer, MenuRouterVO> menuMap = new HashMap<>();for (Menu menu : menuList) {// 处理父级菜单if(menu.getParentId()==0){menuRouterVO = new MenuRouterVO();menuRouterVO.setName(menu.getName());menuRouterVO.setPath(menu.getPath());menuRouterVO.setHidden(menu.getHidden());menuRouterVO.setRedirect("noRedirect");menuRouterVO.setComponent(menu.getComponent());menuRouterVO.setAlwaysShow("true");metaVO = new MetaVO();metaVO.setIcon(menu.getIcon());metaVO.setTitle(menu.getName());menuRouterVO.setMeta(metaVO);menuRouterVO.setChildren(new ArrayList<ChildrenMenuRouterVO>());menuMap.put(menu.getMenuId(), menuRouterVO);}// 处理子菜单else{childrenMenuRouterVO = new ChildrenMenuRouterVO();childrenMenuRouterVO.setName(menu.getName());childrenMenuRouterVO.setPath(menu.getPath());childrenMenuRouterVO.setHidden(menu.getHidden());childrenMenuRouterVO.setComponent(menu.getComponent());metaVO = new MetaVO();metaVO.setIcon(menu.getIcon());metaVO.setTitle(menu.getName());childrenMenuRouterVO.setMeta(metaVO);// 通过父ID直接从Map中获取父菜单并添加子菜单menuMap.get(menu.getParentId()).getChildren().add(childrenMenuRouterVO);}}return new ArrayList<>(menuMap.values());
}

特点分析

  • 时间复杂度为 O (n),效率最高
  • 利用 HashMap 的快速查找特性,减少遍历次数
  • 代码简洁,逻辑清晰
  • 支持多级菜单,但需要确保菜单数据的完整性
  • 适合数据量大、对性能要求高的场景

三种方式对比与选择建议

方式优点缺点适用场景
双重循环实现简单,易于理解仅支持两级菜单,效率低简单的两级菜单,数据量小
递归构建支持无限层级,逻辑清晰时间复杂度高,数据量大时性能差多级菜单,数据量较小
HashMap 映射效率高,支持多级菜单需要额外的 Map 存储,依赖数据完整性数据量大,多级菜单,对性能要求高

在实际开发中,应根据项目的菜单层级需求、数据量大小和性能要求选择合适的实现方式。
对于大多数后台管理系统,HashMap 映射方式是一个兼顾性能和灵活性的不错选择。

http://www.lryc.cn/news/617267.html

相关文章:

  • 邬贺铨院士:AI与数字安全融合是数字化建设核心驱动力
  • 算法73. 矩阵置零
  • Dubbo从入门到实战:分布式服务开发指南
  • React18 Transition特性详解
  • Apache IoTDB 全场景部署:跨「端-边-云」的时序数据库 DB+AI 实战
  • 智能制造算力一体机:工业 4.0 时代的算力基建革命
  • WPF之绑定!
  • 源码分析Eino框架工具调用--创建篇
  • 瑞芯微rk3588:yolov8-obb训练实战笔记
  • 云原生环境 Prometheus 企业级监控实战
  • 容器 K8S Docker Kata 学习(一)
  • k8s的calico是什么作用,举例一下
  • 【软考中级网络工程师】知识点之 UDP 协议:网络通信中的高效轻骑兵
  • k8s PV和PVC开始总结
  • AI时代基于云原生的 CI/CD 基础设施 Tekton
  • RabbitMQ 声明队列和交换机详解
  • HTTPS 协议原理 ——4种方案
  • HTTPS的应用层协议
  • 2024年ESWA SCI1区TOP,自适应种群分配和变异选择差分进化算法iDE-APAMS,深度解析+性能实测
  • 在 ASP.NET 项目中用 C# 生成二维码
  • 为 Promethus 配置https访问
  • 无人机航拍数据集|第12期 无人机停车场车辆计数目标检测YOLO数据集1568张yolov11/yolov8/yolov5可训练
  • FP32、BF16、FP16三种方式比较
  • 计算机视觉CS231n学习(7)
  • 《范仲淹传》读书笔记与摘要
  • MySQL数据库简介
  • MySQL-日志
  • Vue 3 快速入门 第六章
  • Linux操作系统从入门到实战(十九)进程状态
  • JS-第二十三天-正则