list<Menu>集合转成树形结构返回

这篇博客介绍了如何在Java服务层通过迭代和递归方法构建基于用户权限的树形菜单结构。首先,定义了菜单实体类包含菜单ID、名称、父菜单ID及子菜单列表。然后,展示了根据用户ID查询菜单的方法,区分超级管理员和普通用户。核心部分是`getChildPerms`方法,它遍历菜单列表,查找指定父ID的子菜单,并通过`recursionFn`递归填充子节点。最后,文章还讨论了迭代器与增强for循环在遍历时的不同之处。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以这张菜单信息表为例,parent_id指向父id,在这个表中是指向menu_id

 返回这样的数据

这个菜单表的实体: (展示重要的字段)

    /** 菜单ID */
    private Long menuId;

    /** 菜单名称 */
    private String menuName;

    /** 父菜单名称 */
    private String parentName;

    /** 父菜单ID */
    private Long parentId;

.........

    /** 子菜单 */
    private List<SysMenu> children = new ArrayList<SysMenu>();

直接上service.impl层的代码:

     /**
       这个方法是controller调用的方法,根据用户ID查询菜单
     * 
     *
     * @param userId 用户名称
     * @return 菜单列表
     */
    @Override
    public List<SysMenu> selectMenuTreeByUserId(Long userId)
    {
        List<SysMenu> menus = null; // 返回的结果集
        if (SecurityUtils.isAdmin(userId)) // 判断是不是超级管理员
        {
            menus = menuMapper.selectMenuTreeAll();// 是超级管理员返回所有菜单列表
        }
        else // 不是,则按照userId去查询这个用户能查看的所有菜单列表
        {
            menus = menuMapper.selectMenuTreeByUserId(userId);
        }
        // 这里拿到的列表是没有树形结构的
        return getChildPerms(menus, 0);
    }



    /**
     * 根据父节点的ID获取所有子节点
     *
     * @param list 分类表
     * @param parentId 传入的父节点ID
     * @return 这个父id下所有的子菜单
     */
    public List<SysMenu> getChildPerms(List<SysMenu> list, int parentId)
    {
        List<SysMenu> returnList = new ArrayList<SysMenu>();
        // 注释的是迭代器写法,没注释的是增强for循环写法
        /*for (Iterator<SysMenu> iterator = list.iterator(); iterator.hasNext();)
        {
            SysMenu t = (SysMenu) iterator.next();
            // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
            if (t.getParentId() == parentId)
            {
                recursionFn(list, t);
                returnList.add(t);
            }
        }*/

        for (SysMenu t : list){
            // 遍历list找到和传入的parentId相等的数据
            if (t.getParentId() == parentId)
            {
                recursionFn(list, t);
                returnList.add(t);
            }
        }

        return returnList;
    }

    /**
     * 
     * 查这个父节点下面还有没有子节点
     * @param list
     * @param t
     */
    private void recursionFn(List<SysMenu> list, SysMenu t)
    {
        // 得到子节点列表
        List<SysMenu> childList = getChildList(list, t);
        // 添加子节点列表
        t.setChildren(childList);
        // 对子节点列表进行遍历
        for (SysMenu tChild : childList)
        {
            // 判断子节点是否有孩子
            if (hasChild(list, tChild))
            {
                // 有的话,继续递归调用,给这个节点添加子孩子
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 遍历list 得到传入目录下的所有子目录的列表
     */
    private List<SysMenu> getChildList(List<SysMenu> list, SysMenu t)
    {
        List<SysMenu> tlist = new ArrayList<SysMenu>();
        /*Iterator<SysMenu> it = list.iterator();
        while (it.hasNext())
        {
            SysMenu n = (SysMenu) it.next();
            if (n.getParentId().longValue() == t.getMenuId().longValue())
            {
                tlist.add(n);
            }
        }*/

        for (SysMenu n : list){
            if (n.getParentId().longValue() == t.getMenuId().longValue())
            {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<SysMenu> list, SysMenu t)
    {
        return getChildList(list, t).size() > 0;
    }

迭代器遍历元素与增强for循环变量元素的区别:使用迭代器遍历集合的元素时可以删除集合的元素,而增强for循环变量集合的元素时,不能调用迭代器的remove方法删 除 元素。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值