管理系统必备技(1):递归生成树形结构菜单_菜单树形结构_潇雷的博客-程序员宅基地

技术标签: java  项目  

微信公众号:潇雷
当努力到一定程度,幸运自与你不期而遇。

1、概述

后台管理系统是web开发必备的一个项目,因此有必要对系统的一些基本功能做个梳理,今天要看的内容是如何递归生成树形结构菜单,效果图如下:

菜单分为一级菜单、二级菜单、复杂的菜单甚至包含三级菜单和四级菜单,这些数据在表里面都是在一个菜单目录表里。

表的核心设计如下:

字段 名称 备注
id int 主键id
parent_id int 一级菜单为0 ,其他菜单指向父类的id
menu_path varchar 资源路径
sort int 排序
menu_button tinyint 是否作为目录展示,或者隐藏等需求

2、代码实现

思路比较统一:

1、首先找到菜单数据的所有数据

2、然后找到所有的一级菜单,将它的子树拼接上

3、子树也会有子菜单,需要递归拼接子树的子菜单。

首先对原先的实体类,我们需要增加一个字段存放子菜单的列表,加上注解表示该字段不在数据库中拥有。

2.1 基础版实现

  @Override
    public List<ChildMenuVO> listWithTree() {
        //1、查出所有菜单
        List<CategoryEntity> categoryEntities = categoryDao.selectList(null);
        //2、组装成父子的树形结构
        List<ChildMenuVO> childMenuVOS =treeMenu(categoryEntities);
        return childMenuVOS;
    }

    private List<ChildMenuVO> treeMenu(List<CategoryEntity> categoryEntities) {
        List<ChildMenuVO> childMenuVOS=new ArrayList<>();
        for (int i = 0; i < categoryEntities.size(); i++) {
            CategoryEntity categoryEntity=categoryEntities.get(i);
            //如果父id为0 的话,就不执行后续方法
            if(0!=categoryEntity.getParentCid().intValue()){
                continue;
            }
            ChildMenuVO childMenuVO = new ChildMenuVO();
            BeanUtils.copyProperties(categoryEntity,childMenuVO);
            //递归判断 当前menu 是否有子节点,如果有则set
            childMenuVO.setChild(subMenu(categoryEntity,categoryEntities));
            childMenuVOS.add(childMenuVO);
        }
        return childMenuVOS;
    }

    private List<ChildMenuVO> subMenu(CategoryEntity parentMenu, List<CategoryEntity> categoryEntities) {
        List<ChildMenuVO> childMenuVOS =new ArrayList<>();
        //遍历所有目录
        for (int i = 0; i < categoryEntities.size(); i++) {
            CategoryEntity subCategory=categoryEntities.get(i);
            if(subCategory.getParentCid().equals(parentMenu.getCatId())){
                ChildMenuVO childMenuVO = new ChildMenuVO();
                BeanUtils.copyProperties(subCategory,childMenuVO);
                childMenuVO.setChild(subMenu(subCategory,categoryEntities));
                childMenuVOS.add(childMenuVO);
            }
        }
        return childMenuVOS;
    }

2.2 进阶版实现

 public List<CategoryEntity> listWithTree() {
        //1、查出所有菜单
        List<CategoryEntity> categoryEntities = categoryDao.selectList(null);
        //2、组装成父子的树形结构
            //2.1 找到所有的一级分类
            List<CategoryEntity> level1Menus = categoryEntities.stream().filter(categoryEntity -> {
                return categoryEntity.getParentCid() == 0;
            }).map(menu->{
                menu.setChildren(getChildrens(menu,categoryEntities));
                return menu;
            }).sorted((menu1,menu2)->{
                return (menu1.getSort()==null?0:menu1.getSort())-(menu2.getSort()==null?0:menu2.getSort());
            })
              .collect(Collectors.toList());
            return level1Menus;
    }

    //递归找到当前菜单的子菜单
    private List<CategoryEntity> getChildrens(CategoryEntity  root,List<CategoryEntity> all){
        List<CategoryEntity> children = all.stream().filter(categoryEntity -> {
            return categoryEntity.getParentCid().equals(root.getCatId());
        }).map(categoryEntity -> {
            categoryEntity.setChildren(getChildrens(categoryEntity,all));
            return categoryEntity;
        }).sorted((menu1,menu2)->{
            return (menu1.getSort()==null?0:menu1.getSort())-(menu2.getSort()==null?0:menu2.getSort());
        }).collect(Collectors.toList());
        return children;
    }

不得不说java8的stream流极大的简洁了代码,后续也会记录java8的文章,效果也达到了,stream流有点像sql,可以做出排序、过滤、判断等各种简洁的操作。

今天的分享就到这里,有兴趣可以关注,后续更多内容干货敬请期待。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_42184068/article/details/111525711

智能推荐

用adb命令组装PowerShell实用小工具——Android测试小助手_weixin_34218890的博客-程序员宅基地

[本文出自天外归云的博客园]简介APP性能测试一般对以下几个方面进行测试:1.启动时间(可以通过本工具测试);2.CPU的占用(可以通过本工具测试);3.内存的占用(可以通过本工具测试);4.流量的耗用(可以通过本工具测试);5.电量的耗用(用户实际使用中感知即可)。除了可以做以上这几个专项测试外,本工具还能进行monkey测试等等...

PAT甲级2019春季真题题解_2019 pat春季题解-程序员宅基地

PAT甲级2019春季题目及满分代码下载A Sexy Primes  签到题,素数不需要用筛法,直接O(sqrt(n))即可。#include<iostream>using namespace std;bool check(int a) { if (a < 2) return false; for (int i = 2; i * i <= a; i++) if (a % i == 0) retur_2019 pat春季题解

高通平台调试中遇到的SPI问题_qupv3l_model_gsi_就叫者行孙吧的博客-程序员宅基地

最近在bring up ak7739这颗codec的时候遇到一个spi问题。开机在spi_probe函数中调用spi_write机器就会dump,log如下:代码是这样的:同时tz那边也给了相应的权限{ QUPV3_1_SE1, QUPV3_PROTOCOL_SPI, QUPV3_MODE_GSI, AC_HLOS, FALSE, TRUE, TRUE },看这个dump的Call trace,跟dma扯上了关系,猜测应该是和buffer相关,然后将tz中bAllowFifo标志改成_qupv3l_model_gsi

用python从一个文件(.txt)中读取数据写入到另一个文件(.txt)中_学渣记录的博客-程序员宅基地

用python从一个文件(.txt)中读取数据写入到另一个文件(.txt)中import osfile_list=[]#从PaddleDetection/dataset/fruit/fruit-detection/ImageSets/Main文件夹下的train.txt文件中读取数据with open(r’PaddleDetection/dataset/fruit/fruit-detection/ImageSets/Main/train.txt’) as f1:cNames = f1.readli

Mybatis逆向工程详解及源码下载_反向工程代码下载_Mr微笑的博客-程序员宅基地

什么是逆向工程 MyBatis的一个主要的特点就是需要程序员自己编写sql,那么如果表太多的话,难免会很麻烦,所以mybatis官方提供了一个逆向工程,可以针对单表自动生成mybatis执行所需要的代码(包括mapper.xml、mapper.java、po..)。一般在开发中,常用的逆向工程方式是通过数据库的表生成代码。1:mybatis逆向工程开发源码:https://do..._反向工程代码下载

使用requests库实现多线程下载_dejing6575的博客-程序员宅基地

多线程下载主要用到http请求中的headerContent-Length:资源长度,用于确认资源的总长度,从而便于规划每个线程的任务量Range:bytes=beg1-end1;beg2-end2,用来控制下载的资源的某一部分,需要注意,这里的beg、end是前闭后闭区间。当下载的片段较小时,很容易出错,需要重试,可以使用retry模块通过注解方式实现重试,这个模块非常好用。...

随便推点

Quick JavaScript Interview Questions(JavaScript面试宝典)电子书分享_chongyuwan4121的博客-程序员宅基地

CreateSpace Quick JavaScript Interview Questions Learn Frequently Asked Questions.pdf 本书描述 这本书是关于javascript中的关键概念的。这本书收集javascript面试中的一系列常见的问题...

实验10:配置RIPv2的认证_ripv2认证_☆★☆★☆★☆★☆☆★☆★的博客-程序员宅基地

步骤一查看路由表,抓包,验证安全!配置过后,查看R1和R2的路由表信息。现在的路由表上的信息是正常的,R3发送的欺骗路由在表中消失了,与简单验证配置的结果一致。抓包查看现象:此时不显示密码内容。_ripv2认证

英文履历_weixin_30760895的博客-程序员宅基地

英文履历 英文履历:电脑程序员[ 2006-03-28 15:39 ]一份漂亮的英文履历可以让你的求职简历增色不少。下面是一位电脑程序员的履历表,希望可以给各位程序员GGMM一点启示哦!Gang XuSouth China Computer Company23 South Xianlie RoadGuangzhou, Guangdong...

Vs code快捷键及常用插件_visual studio code左侧插件出不来_孤独与生俱来的博客-程序员宅基地

前言本文的最新内容,更新于 2020-06-19。大家完全不用担心这篇文章会过时,因为随着 VS Code 的版本更新和插件更新,本文也会随之更新。本文的最新内容,也会在GitHub上同步更新,欢迎 star。VS Code 软件实在是太酷、太好用了,越来越多的新生代互联网青年正在使用它。前端男神尤雨溪大大这样评价 VS Code:有一点你可能会感到惊讶:VS Code 这款软件本身,是用 JavaScript 语言编写的(具体请自行查阅基于 JS 的客户端开发框架 Electron)._visual studio code左侧插件出不来

hihoCoder1227 The Cats' Feeding Spots 二分_hihocoder 1227_AC_Gibson的博客-程序员宅基地

题目链接:http://hihocoder.com/problemset/problem/1227题目大意:平面上有m个点,要从这m个点当中找出n个点,使得包含这n个点的圆的半径(圆心为n个点当中的某一点且半径为整数)最小,同时保证圆周上没有点。分析:枚举这m个点,以每个点为圆心找出一个符合条件的半径,然后找出这些半径中的最小值即可。至于如何找出半径,我们可以二分[-100_hihocoder 1227

android缓存作用是什么,android 实现清理缓存功能_三十年老生的博客-程序员宅基地

很多App设置里面都会有清理缓存这个小功能,当我们app所浏览一些图片啊,或者信息,都会缓存起来,包括存在本地的一些数据,这些呢会使我们app占用的内存变大,但是会节省我们的流量使用,我们清理缓存后占用内存就会小很多,下面进行我们的代码 首先 我们要一个工具类,这个工具类是用来清理缓存的,调用里面的方法就可以public class DataCleanManager {/*** * 清除本应用..._android缓存的目的

推荐文章

热门文章

相关标签