项目需求:
在项目对接过程中,被调用方给返回了一个对象列表,对象中包含id和parentId,但返回的数据没有层级结构,需要调用方自己组装成树级结构;
需求分析:
由于返回的是否无序的列表,首先需要找到顶级结构,然后更加parentId获取子级,递归循环,指定子级没有后代信息;
需求实现:
想到两种方式:
第一种、首先想到的是循环列表,对一个列表进行多次循环,每次只找一级,即可实现;
第二种、先根据parentId聚合,然后再对聚合map进行递归;
相对来说第二种方式,比较合适;但是需要考虑到parentId不存在的情况;
- 先找到顶级,过滤条件为parentId不存在:
//没有parentid
List<TemplateInfo> topList =
templateInfoList.stream()
.filter(templateInfo -> !StringUtils.hasText(templateInfo.getFdParentId()))
.collect(Collectors.toList());
- 剩下的是有parentid属性的列表:
//非顶级目录
List<TemplateInfo > childList =
templateInfoList.stream()
.filter(templateInfo -> StringUtils.hasText(templateInfo.getFdParentId()))
.collect(Collectors.toList());
- 对非顶级目录进行groupingby聚合
Map<String,List<TemplateInfo>> parentIdMap = childList.stream().collect(Collectors.groupingBy(TemplateInfo::getFdParentId));
- 比较parentId和id集合,获取到顶级下的第二级
对两个id列表进行set,然后通过set的removeAll方法过滤到id
Set<String> idSet = childList.stream().map(templateInfo -> templateInfo.getFdId()).collect(Collectors.toSet());
Set<String> parentIdSet = parentIdMap.keySet();
HashSet<String> set = new HashSet<>();
set.addAll(parentIdSet);
set.removeAll(idSet); //剩下的就是顶级目录
- 对map进行递归操作,添加到后代节点;
List<CategoryInfo> categoryInfos = new ArrayList<>();
for (String parentId : set) {
categoryInfos.addAll(genTree(parentId,parentIdMap,1));
}
递归函数
public List<CategoryInfo> genTree(String parentId,Map<String,List<TemplateInfo>> parentIdMap,int level){
List<CategoryInfo> categoryInfoList = new ArrayList<>();
List<TemplateInfo> templateInfos = parentIdMap.get(parentId);
if(templateInfos==null){
//do noting
}else{
level = level + 1;
System.out.println(level+"==" + parentId);
for (TemplateInfo templateInfo:templateInfos) {
List<InnerCategoryInfo> chlidList = genTree(templateInfo.getFdId(),parentIdMap,level);
InnerCategoryInfo categoryInfo = new InnerCategoryInfo(templateInfo.getFdId(),
templateInfo.getFdName(),templateInfo.getFdParentId(),level,chlidList);
categoryInfoList.add(categoryInfo);
}
}
return categoryInfoList;
}
- 之前由于对list列表以parentId为key进行聚合,如果parentId为null或空字符串,聚合时会报错,所以排除了parentId不存在的对象;这里需要添加到顶级
public List<CategoryInfo> genTree(List<TemplateInfo> templateInfoList){
List<CategoryInfo> top = new ArrayList<>();
if(topList!=null && topList.size() > 0){
Map<String,List<CategoryInfo>> categoryInfoTop =
categoryInfos.stream().collect(Collectors.groupingBy(CategoryInfo::getParentId));
for (TemplateInfo t : topList) {
InnerCategoryInfo info = new CategoryInfo(t.getFdId(),t.getFdName(),
t.getFdParentId(),0,categoryInfoTop.get(t.getFdId()));
top.add(info);
}
categoryInfos = top;
}
return categoryInfos;
}
其他实现方法:
以上实现方法,还是有点麻烦,还在找一种更方便快速的方法实现;