JAVA 递归实现

方法一

Java8 简单实现递归 (树形展示)
在这里插入图片描述

/**
     * 获取选择弹窗
     * @param prodClassNm   某一层条件   TODO 
     * @param prodType      某类型
     * @return
     */
    public List<ProdClassSelectPopVo> getProdClassSelectPop(String prodClassNm, String prodType) {
        List<ProdClassSelectPopVo> treeList = new ArrayList<>();
        // 获取所有商品分类
        List<ProdClassSelectPopVo> allList = mproductClassListDao.getProdClassSelectPop(prodType);
        if(CollectionUtil.isNotEmpty(allList)){
            // 1、获取所有数据中过滤一级菜单 2、Map中通过递归函数获取一级节点中的子节点列表
            treeList = allList.stream().filter(subNode -> StringUtils.isNullOrEmpty(subNode.getParentClass())
                            && (subNode.getId() + "/").equals(subNode.getPath()))
                    .map(m -> getChild(m,allList,prodClassNm)).collect(Collectors.toList());
        }
        if(StringUtils.isNotEmpty(prodClassNm)){
            treeList = treeList.stream().filter(f -> CollectionUtil.isNotEmpty(f.getChildren().stream()
                    .filter(item -> item.getProdClassNm().contains(prodClassNm)).collect(Collectors.toList()))
            ).collect(Collectors.toList());
        }
        return treeList;
    }
    /**
     * 递归辅助函数
     * @param parent 上级节点
     * @param allList 所有数据
     * @return
     */
    private ProdClassSelectPopVo getChild(ProdClassSelectPopVo parent,List<ProdClassSelectPopVo> allList,String prodClassNm){
        List<ProdClassSelectPopVo> treeVo = allList.stream()
                .filter(subNode -> StringUtils.isNotEmpty(subNode.getParentClass())
                        && subNode.getParentClass().equals(parent.getId())).map(m -> getChild(m,allList,prodClassNm)).collect(Collectors.toList());
                        // && subNode.getPath().equals(parent.getId() + "/" +subNode.getId() + "/")).collect(Collectors.toList());
                //.map(m -> getChild(m,allList))
        if(StringUtils.isNotEmpty(prodClassNm)){
            treeVo = treeVo.stream().filter(f -> f.getProdClassNm().contains(prodClassNm)).collect(Collectors.toList());
        }
        parent.setChildren(treeVo);
        return parent;
    }

方法二

商品分类树的数据构造
商品分类表结构
使用stream流来构造一级分类信息

/1、获取所有的一级分类信息
List<CategoryEntity> level1Menus = entities.stream().filter((categoryEntity -> categoryEntity.getParentCid() == 0)).collect(Collectors.toList());CategoryEntity中添加子分类的字段
/**
 * 定义子分类信息,此字段在表里不存在
 */
@TableField(exist = false)
private List<CategoryEntity> children;

递归获取一级分类下的子分类
首先对上面获取一级分类的方法进行改造一下,如下代码段:

@Override
    public List<CategoryEntity> listWithTree() {
        //查询出所有分类信息
        List<CategoryEntity> entities = baseMapper.selectList(null);

        //组装成父子结构
          //1、获取所有的一级分类信息
//        List<CategoryEntity> level1Menus = entities.stream().filter((categoryEntity -> categoryEntity.getParentCid() == 0)).collect(Collectors.toList());
         // 2、一级菜单组装完成后,我们再根据一级分类获取其下级分类,所以需要将上面的代码改造一下
        List<CategoryEntity> level1Menus = entities.stream()
                //过滤出一级分类
                .filter((categoryEntity -> categoryEntity.getParentCid() == 0))
                .map((menu)->{ //和peek的区别?
                    //重新组装一级分类的信息,设置其子分类,传递参数{当前节点、所有的节点}
                    menu.setChildren(getChildrens(menu,entities));
                    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() == root.getCatId();
    })).map((childMenu) -> {
        //递归调用,根据当前菜单找出其子菜单
        childMenu.setChildren(getChildrens(childMenu, all));
        return childMenu;
    }).sorted((menu1, menu2) -> {
        //排序规则:前面菜单的顺序-后面菜单的顺序的差值
        return (menu1.getSort()==null?0:menu1.getSort()) - (menu2.getSort()==null?0:menu2.getSort());
    }).collect(Collectors.toList());

    return children;
}

方法三

无参数递归

/**
     * 根据用户ID获取角色
     */
    public List<Role> getRoleByUserId(String userId) {
        List<Role> result = new ArrayList<>();
        // 获取所有用户角色
        List<Role> allUserRoleInfo = roleDao.getAllUserRoleInfo();
        if(CollectionUtil.isNotEmpty(allUserRoleInfo)){
            result = buildRoleTree(allUserRoleInfo,userId);
        }
        return result;
    }

    /**
     * 角色树组装
     * @param allRoleList
     * @return
     */
    private static List<Role> buildRoleTree(List<Role> allRoleList,String userId){
        List<Role> result = new ArrayList<>();
        for (Role role : allRoleList){
            // 如果是顶级节点,遍历该父节点所有子节点
            if(StringUtils.isNullOrEmpty(role.getParentId()) && Objects.equals(role.getUserId(),userId)){
                recursionRoleFn(allRoleList,role,userId);
                result.add(role);
            }
        }
        return result;
    }

    /**
     * 递归列表
     * 结束条件为所遍历的节点无下一级节点
     * @param allRoleList  所有角色数据
     * @param parent 顶级节点
     */
    private static void recursionRoleFn(List<Role> allRoleList,Role parent,String userId){
        // 得到子节点列表
        List<Role> childList = getRoleChildList(allRoleList,parent,userId);
        parent.setChildren(childList);
        for (Role o : childList){
            // 如果子节点有下一级节点,得到下一级的节点列表
            if(hasRoleChild(allRoleList,o,userId)){
                recursionRoleFn(allRoleList,o,userId);
            }
        }
    }
    /**
     * 获得该节点的下一级子节点列表
     * @param allRoleList  所有角色数据
     * @param parent 顶级节点
     * @param allRoleList
     */
    private static List<Role> getRoleChildList(List<Role> allRoleList,Role parent,String userId){
        List<Role> roleList = new ArrayList<>();
        for (Role r : allRoleList){
            // 遍历非顶级节点,并获得传入参数顶级节点的下一级子节点列表
            if(StringUtils.isNotEmpty(r.getParentId()) && r.getParentId().equals(parent.getModuleId()) && Objects.equals(r.getUserId(),userId)){
                roleList.add(r);
            }
        }
        return roleList;
    }

    /**
     * 判断是否有子节点
     * @param roleList 节点列表
     * @param role 角色节点
     * @return boolean
     */
    private static boolean hasRoleChild(List<Role> roleList,Role role,String userId){
        return CollectionUtil.isNotEmpty(getRoleChildList(roleList, role,userId));
    }

有参递归

 /**
     * 根据指定模块树节点获得模块树【系统模块一览】
     * @param module 模块树节点 【参数】
     * @return
     */
    public List<Module> listModuleTreeNew(Module module) {
        List<Module> resultModule = new ArrayList<>();
        // 获取所有模块
        List<Module> allModules = moduleDao.getAllModuleInfo();
        if(!CollectionUtil.isNotEmpty(allModules)){
            return resultModule;
        }
        // 获取模块编号集合
        List<Module> moduleCds = new ArrayList<>();
        // 获取模块名称集合
        List<Module> moduleNms = new ArrayList<>();
        // 按照条件检索
        if(null != module && StringUtils.isNotEmpty(module.getModuleCd())){
            moduleCds = allModules.stream().filter(f -> f.getModuleCd().contains(module.getModuleCd())).collect(Collectors.toList());
        }
        if(null != module && StringUtils.isNotEmpty(module.getModuleNm())){
            moduleNms = allModules.stream().filter(f -> f.getModuleNm().contains(module.getModuleNm())).collect(Collectors.toList());
        }
        resultModule = buildModuleTree(allModules,moduleCds,moduleNms);
        return resultModule;
    }

    /**
     * 建立模块树
     * @param allModules
     * @return
     */
    private static List<Module> buildModuleTree(List<Module> allModules,List<Module> moduleCds,List<Module> moduleNms){
        List<Module> result = new ArrayList<>();
        List<Module> removeList = new ArrayList<>();
        for (Module m : allModules){
            // 如果是顶级节点,遍历该节点所有子节点
            if((!CollectionUtil.isNotEmpty(moduleCds) && !CollectionUtil.isNotEmpty(moduleNms) && StringUtils.isNullOrEmpty(m.getParentId()))
                    || (CollectionUtil.isNotEmpty(moduleCds) && !CollectionUtil.isNotEmpty(moduleNms)
            && moduleCds.stream().map(MModule::getId).collect(Collectors.toList()).contains(m.getId()))
                    || (!CollectionUtil.isNotEmpty(moduleCds) && CollectionUtil.isNotEmpty(moduleNms)
            && moduleNms.stream().map(MModule::getId).collect(Collectors.toList()).contains(m.getId()))
                    || (CollectionUtil.isNotEmpty(moduleCds) && CollectionUtil.isNotEmpty(moduleNms)
            && moduleCds.stream().map(MModule::getId).collect(Collectors.toList()).contains(m.getId())
            && moduleNms.stream().map(MModule::getId).collect(Collectors.toList()).contains(m.getId()))
            ){
                // 第一行无参数时;第二三行当编号有值名称无值时;第四五行编号无值,名称有值时;第六行:编号和名称均有值时
                recursionFn(allModules,m);
                result.add(m);
            }else {
                removeList.add(m);
            }
        }
        if(CollectionUtil.isNotEmpty(removeList)){
            allModules.removeAll(removeList);
        }
        if(!CollectionUtil.isNotEmpty(result)){
            result = allModules;
        }
        return result;
    }
    /**
     * 递归列表
     * 结束条件为所遍历的节点无下一级节点
     * @param allModules  所有模块数据
     * @param parent 顶级节点
     */
    private static void recursionFn(List<Module> allModules,Module parent){
        // 得到子节点列表
        List<Module> childList = getChildList(allModules,parent);
        parent.setChildren(childList);
        for (Module m : childList){
            // 如果子节点有下一级节点,得到下一级的节点列表
            if(hasChild(allModules,m)){
                recursionFn(allModules,m);
            }
        }
    }

    /**
     * 获得该节点的下一级子节点列表
     * @param allModules  所有模块数据
     * @param parent 顶级节点
     */
    private static List<Module> getChildList(List<Module> allModules,Module parent){
        List<Module> orgList = new ArrayList<>();
        for (Module o : allModules){
            // 遍历非顶级节点,并获得传入参数顶级节点的下一级子节点列表
            if(StringUtils.isNotEmpty(o.getParentId()) && o.getParentId().equals(parent.getId())){
                orgList.add(o);
            }
        }
        return orgList;
    }

    /**
     * 判断是否有子节点
     * @param moduleListList 节点列表
     * @param moduleTree 模块节点
     * @return boolean
     */
    private static boolean hasChild(List<Module> moduleListList,Module moduleTree){
        return CollectionUtil.isNotEmpty(getChildList(moduleListList, moduleTree));
    }

  • 9
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值