Java中实现多级菜单的列表(递归排序)

一、项目背景

由于最近项目中需要实现展示菜单功能,菜单是需要多级,并且级数不固定。像这种需求,一般就是用递归实现了,可以从第一级一直往下查,一直查询到为空为止。

二、数据库实体类字段

  1. 两个实体类,一个是对应数据库的实体类,VO是返回给前端的实体类
public class RcMenu {
	
	private Integer menuId; //菜单ID
	
	private String menuName;//菜单名称
	
	private Boolean status; //菜单状态
	
	private String level; 	//菜单级别
	
	private Integer parentId; //父类ID
	
	private Integer sortOrder; //排序
	
}
public class RcMenuVO {
	
	private Integer menuId; //菜单ID
	
	private String menuName;//菜单名称
	
	private Boolean status; //菜单状态
	
	private String level; 	//菜单级别
	
	private Integer parentId; //父类ID
	
	private Integer sortOrder; //排序
	
	//存放子菜单目录
	private List<RcMenuVO> children;

}

三、项目中代码实现

	/**
	 * 对象实体类转换
	 * @param rcMenu
	 * @return
	 */
	private RcMenuVO rcMenuTORcMenuVO(RcMenu rcMenu) {
		RcMenuVO rcMenuVO = new RcMenuVO();
		BeanUtils.copyProperties(rcMenu, rcMenuVO);
		return rcMenuVO;
	}


	/**
     * 根据一级递归调用子级
     *	reversed方法 表示数字越大靠前
     * @param menuList
     * @param rootMenuList
     * @return
     */
    private void findSubCategory(List<RcMenu> menuList, List<RcMenuVO> rootMenuList) {
        // 遍历一级
        for (RcMenuVO rcMenuVO : rootMenuList) {
            List<RcMenuVO> rcMenuVOList = new ArrayList<>();
            // 查找子级
            for (RcMenu rcMenu : menuList) {
                // 判断当前目录是否是子父级关系
                if (rcMenuVO.getMenuId().equals(rcMenu.getParentId())) {
                	rcMenuVOList.add(rcMenuTORcMenuVO(rcMenu));
                }
                // 递归调用,不管有几级菜单,都能够适用
                findSubCategory(menuList, rcMenuVOList);
                // 类目显示排序,
                rcMenuVOList.sort(Comparator.comparing(RcMenuVO::getSortOrder));
            }
            // 最后把查到的子级保存到一级目录中
            rcMenuVO.setChildren(rcMenuVOList);
        }
    }

	/**
	 * 	各级菜单列表展示
	 * @param menu
	 * @param pageObject
	 * @return
	 */
	public List<RcMenuVO> queryMenuList(RcMenu menu, PageObject pageObject) {
		List<RcMenu> menuList = null;
		Page<RcMenu> page = PageHelper.startPage(pageObject.getPageNum(), pageObject.getPageSize());
		// 将用户页面提交的参数拷贝到查询条件去
		SpringBeanUtils.copyPropertiesIgnoreNull(pageObject, page);
		//先查出全部菜单
		menuList = menuMapper.queryMenuList(menu);
		
		//获取一级菜单	0代表一级菜单 .reversed()
		List<RcMenuVO> rootMenuList = menuList.stream()
				.filter(e -> e.getParentId().equals(0))
				.map(this::rcMenuTORcMenuVO)
				.sorted(Comparator.comparing(RcMenuVO::getSortOrder))
				.collect(Collectors.toList());
		//查找字节点
		findSubCategory(menuList,rootMenuList);
		
		// 将真实分页信息拷贝到用户页面
		SpringBeanUtils.copyPropertiesIgnoreNull(page, pageObject);
		//返回值		
		return rootMenuList;
	}

	
	/**
	 * 	根据菜单id 查找子菜单
	 * @param menuId
	 * @return
	 */
	public List<RcMenuVO> queryMenuById(RcMenu menu) {
		//先查出菜单
		List<RcMenu> menuList = menuMapper.queryMenuList(menu);
		//获取一级菜单	0代表一级菜单 .reversed()
		List<RcMenuVO> rootMenuList = menuList.stream()
				.filter(e -> e.getParentId().equals(0))
				.map(this::rcMenuTORcMenuVO)
				.sorted(Comparator.comparing(RcMenuVO::getSortOrder))
				.collect(Collectors.toList());
		//查找字节点
		findSubCategory(menuList,rootMenuList);
		//返回值		
		List<RcMenuVO> rootMenu = new ArrayList<RcMenuVO>();
		for (int i = 0; i < rootMenuList.size(); i++) {
			if (rootMenuList.get(i).getMenuId().equals(menu.getMenuId())) {
				RcMenuVO rcMenuVO = rootMenuList.get(i);
				rootMenu.add(rcMenuVO);
			}
		}
		return rootMenu;
	}
	

四、返回的result值 如下:

	{
    "successful": true,
    "data": [
        {
            "menuId": 1,
            "menuName": "菜单",
            "createTime": "2020-05-22",
            "status": "启用",
            "level": "一级菜单",
            "parentId": 0,
            "sortOrder": 0,
            "children": [
                {
                    "menuId": 2,
                    "menuName": "菜单111",
                    "createTime": "2020-05-22",
                    "level": "二级菜单",
                    "parentId": 1,
                    "sortOrder": 1,
                    "status": "停用"
                },
                {
                    "menuId": 3,
                    "menuName": "菜单222",
                    "createTime": "2020-05-22",
                    "level": "二级菜单",
                    "parentId": 1,
                    "sortOrder": 2,
                    "status": "启用"
                }
            ]
        }
    ],
    "page": null,
    "resultHint": "{\"message\":\"数据查询成功\"}",
    "errorPage": "",
    "draw": 0,
    "recordsTotal": 0,
    "recordsFiltered": 0,
    "type": "info"
}
  • 10
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论
### 回答1: Java递归可以用于动态多级菜单的创建和展示。具体步骤如下: 1. 定义菜单项类,包含名称、子菜单等属性。 2. 定义一个递归方法,用于遍历当前菜单项的子菜单,并生成HTML代码来显示菜单。 3. 在递归方法,如果当前菜单项有子菜单,则递归调用该方法,直到没有子菜单为止。 4. 在HTML嵌入递归方法生成的代码,即可显示动态多级菜单。 示例代码如下: ```java public class MenuItem { private String name; private List<MenuItem> subMenu; // getter and setter methods } public class Menu { private List<MenuItem> menuItems; // getter and setter methods //递归方法,生成HTML代码 public String generateHTML() { StringBuilder sb = new StringBuilder(); sb.append("<ul>"); for (MenuItem item : menuItems) { sb.append("<li>"); sb.append(item.getName()); if (item.getSubMenu() != null && item.getSubMenu().size() > 0) { sb.append(item.getSubMenu().generateHTML()); } sb.append("</li>"); } sb.append("</ul>"); return sb.toString(); } } ``` 调用方式: ```java Menu menu = new Menu(); // 添加菜单项及子菜单 String html = menu.generateHTML(); // 将html嵌入到页面显示 ``` 以上是简单的实现,具体实现方式会因为实际需求的不同而有所差异。 ### 回答2: 在Java,我们可以使用递归实现动态多级菜单。 首先,我们可以创建一个Menu类,其包含菜单的名称和一个子菜单列表。然后,我们可以定义一个方法来打印菜单。在该方法,我们可以使用递归来遍历菜单,并打印每个菜单项以及其子菜单。 为了实现递归,我们可以使用一个帮助方法来打印菜单项及其子菜单。此方法会接收一个Menu对象作为参数,并打印菜单的名称,然后遍历该菜单的子菜单列表。如果子菜单列表不为空,我们就可以使用递归来调用此方法,以打印子菜单及其子菜单的子菜单。 下面是一个示例代码: ```java class Menu { private String name; private List<Menu> subMenus; public Menu(String name) { this.name = name; this.subMenus = new ArrayList<>(); } public void addSubMenu(Menu menu) { this.subMenus.add(menu); } public void printMenu() { printMenu(this); } private void printMenu(Menu menu) { System.out.println(menu.name); for (Menu subMenu : menu.subMenus) { printMenu(subMenu); } } } public class Main { public static void main(String[] args) { Menu menu1 = new Menu("菜单1"); Menu menu2 = new Menu("菜单2"); Menu menu3 = new Menu("菜单3"); Menu subMenu1 = new Menu("子菜单1"); Menu subMenu2 = new Menu("子菜单2"); menu1.addSubMenu(subMenu1); menu1.addSubMenu(subMenu2); menu1.addSubMenu(menu2); menu2.addSubMenu(menu3); menu1.printMenu(); } } ``` 此示例代码,我们创建了一个包含多级菜单的菜单结构,并使用printMenu方法打印了所有菜单项。运行此代码,将会输出以下内容: ``` 菜单1 子菜单1 子菜单2 菜单2 菜单3 ``` 通过使用递归,我们可以灵活地实现动态多级菜单。无论菜单层级有多深,都可以使用相同的方法来打印菜单。 ### 回答3: 在Java实现递归动态多级菜单的方法如下: 首先,创建一个菜单项类Menu,该类包含菜单项的名称和子菜单列表。菜单项的子菜单列表也是Menu对象的集合。 在Menu类,我们定义一个递归方法printMenu,用于打印菜单项及其子菜单。在printMenu方法,我们首先打印当前菜单项的名称,然后遍历子菜单列表递归调用printMenu方法打印子菜单项。 接下来,在主函数,我们创建多级菜单结构。可以通过手动创建菜单项的方式,也可以通过解析外部数据文件(如JSON或XML)的方式动态创建菜单项。 最后,我们调用菜单根节点的printMenu方法,即可打印出菜单的整个层级结构。 下面是一个简单的示例代码: ```java class Menu { private String name; private List<Menu> subMenus; public Menu(String name) { this.name = name; this.subMenus = new ArrayList<>(); } public void addSubMenu(Menu subMenu) { subMenus.add(subMenu); } public void printMenu() { System.out.println(name); for (Menu subMenu : subMenus) { subMenu.printMenu(); } } } public class Main { public static void main(String[] args) { Menu rootMenu = new Menu("菜单"); Menu menu1 = new Menu("菜单1"); Menu menu2 = new Menu("菜单2"); Menu menu3 = new Menu("菜单3"); rootMenu.addSubMenu(menu1); rootMenu.addSubMenu(menu2); rootMenu.addSubMenu(menu3); Menu menu11 = new Menu("菜单1-1"); Menu menu12 = new Menu("菜单1-2"); menu1.addSubMenu(menu11); menu1.addSubMenu(menu12); menu2.addSubMenu(new Menu("菜单2-1")); rootMenu.printMenu(); } } ``` 以上代码将会输出如下结果: 菜单 菜单1 菜单1-1 菜单1-2 菜单2 菜单2-1 菜单3 这样,我们就实现递归动态多级菜单的功能。无论菜单结构有多复杂,只需要递归调用printMenu方法,就能打印出整个菜单的层级结构。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Monika、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值