方法一
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));
}