zl程序教程

您现在的位置是:首页 >  Java

当前栏目

java将有父子关系的list转换为树形结构

2023-02-25 18:17:12 时间

项目需求:

在项目对接过程中,被调用方给返回了一个对象列表,对象中包含id和parentId,但返回的数据没有层级结构,需要调用方自己组装成树级结构;

需求分析:

由于返回的是否无序的列表,首先需要找到顶级结构,然后更加parentId获取子级,递归循环,指定子级没有后代信息;

需求实现:

想到两种方式:

第一种、首先想到的是循环列表,对一个列表进行多次循环,每次只找一级,即可实现;

第二种、先根据parentId聚合,然后再对聚合map进行递归;

相对来说第二种方式,比较合适;但是需要考虑到parentId不存在的情况;

  • 先找到顶级,过滤条件为parentId不存在://没有parentid List<TemplateInfo> topList = templateInfoList.stream() .filter(templateInfo -> !StringUtils.hasText(templateInfo.getFdParentId())) .collect(Collectors.toList()); //非顶级目录 List<TemplateInfo > childList = templateInfoList.stream() .filter(templateInfo -> StringUtils.hasText(templateInfo.getFdParentId())) .collect(Collectors.toList()); Map<String,List<TemplateInfo>> parentIdMap = childList.stream().collect(Collectors.groupingBy(TemplateInfo::getFdParentId));
  • 剩下的是有parentid属性的列表:
  • 对非顶级目录进行groupingby聚合
  • 比较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;
    }

其他实现方法:

以上实现方法,还是有点麻烦,还在找一种更方便快速的方法实现;