树形结构的逐级汇总实例

一 场景:假如有如下树形结构,V0到v14都为schoolVO,分别都有老师1位,学生2位,要求逐层(包括自身值)统计出每层的树节点都有总共多少名老师和学生,比如v11的结果等于v11自身+v13+v14

二 设计过程

1 创建学校实例

@Data
@Builder
public  class SchoolVO {
    //教师人数
    private Integer teacherNum;
    //学生人数
    private Integer studentNum;
    //学校名称
    private String name;
    //子级school
    private List<SchoolVO> subSchoolVOList;

}

2 单字段汇总实现方法,比如单独汇总出学生多少人和老师多少人(以下是独立汇总老师数量的实现)

    int statisticslBySign(SchoolVO SchoolVO) {
        List<SchoolVO> SchoolVOList = SchoolVO.getSubSchoolVOList();
        if (SchoolVOList == null) {
            return SchoolVO.getTeacherNum();
        }
        int sum = SchoolVO.getTeacherNum();
        for (SchoolVO SchoolVO1 : SchoolVOList) {
            sum = sum + statisticslBySign(SchoolVO1);
        }
        SchoolVO.setTeacherNum(sum);
        return sum;
    }

3 单字段汇总会导致重复的递归和计算,可以采取多字段联合汇总,实现方式如下

3.1 先创建联合汇总的VO

    @Data
    class StatisticsVO {
        private Integer teacherNum;
        private Integer studentNum;

    }

3.2 递归联合汇总

    //多字段同时逐级累加
    StatisticsVO statisticsByOverall(SchoolVO schoolVO) {
        List<SchoolVO> SchoolVOList = schoolVO.getSubSchoolVOList();
        if (SchoolVOList == null) {
            StatisticsVO statisticsVO = new StatisticsVO();
            statisticsVO.setStudentNum(schoolVO.getStudentNum() == null ? 0 : schoolVO.getStudentNum());
            statisticsVO.setTeacherNum(schoolVO.getTeacherNum() == null ? 0 : schoolVO.getTeacherNum());
            return statisticsVO;
        }
        Integer totalStudentNum = schoolVO.getStudentNum() == null ? 0 : schoolVO.getStudentNum();
        Integer totalTeacherNum = schoolVO.getTeacherNum() == null ? 0 : schoolVO.getTeacherNum();
        for (SchoolVO SchoolVO1 : SchoolVOList) {
            StatisticsVO statisticsVO = statisticsByOverall(SchoolVO1);
            totalStudentNum = totalStudentNum + statisticsVO.getStudentNum();
            totalTeacherNum = totalTeacherNum + statisticsVO.getTeacherNum();
        }
        schoolVO.setTeacherNum(totalTeacherNum);
        schoolVO.setStudentNum(totalStudentNum);
        StatisticsVO statisticsVO = new StatisticsVO();
        statisticsVO.setTeacherNum(totalTeacherNum);
        statisticsVO.setStudentNum(totalStudentNum);
        return statisticsVO;
    }

三 测试用例:本文代码实现技术采用springBoot,代码只截取了关键部分

 1  构建树形结构,从最父级学校逐级往下set子级学校VO

    public void initOrResetTreeInfo() {
        SchoolVO v0 = SchoolVO.builder().name("v0").teacherNum(1).studentNum(2).build();
        SchoolVO v1 = SchoolVO.builder().name("v1").teacherNum(1).studentNum(2).build();
        SchoolVO v2 = SchoolVO.builder().name("v2").teacherNum(1).studentNum(2).build();
        List<SchoolVO> SchoolVOList = Arrays.asList(v1, v2);
        v0.setSubSchoolVOList(SchoolVOList);

        SchoolVO v3 = SchoolVO.builder().name("v3").teacherNum(1).studentNum(2).build();
        SchoolVO v4 = SchoolVO.builder().name("v4").teacherNum(1).studentNum(2).build();
        SchoolVOList = Arrays.asList(v3, v4);
        v1.setSubSchoolVOList(SchoolVOList);
        SchoolVO v5 = SchoolVO.builder().name("v5").teacherNum(1).studentNum(2).build();
        SchoolVO v6 = SchoolVO.builder().name("v6").teacherNum(1).studentNum(2).build();
        SchoolVOList = Arrays.asList(v5, v6);
        v2.setSubSchoolVOList(SchoolVOList);
        SchoolVO v7 = SchoolVO.builder().name("v7").teacherNum(1).studentNum(2).build();
        SchoolVO v8 = SchoolVO.builder().name("v8").teacherNum(1).studentNum(2).build();
        SchoolVOList = Arrays.asList(v7, v8);
        v3.setSubSchoolVOList(SchoolVOList);
        SchoolVO v9 = SchoolVO.builder().name("v9").teacherNum(1).studentNum(2).build();
        SchoolVO v10 = SchoolVO.builder().name("v10").teacherNum(1).studentNum(2).build();
        SchoolVO v11 = SchoolVO.builder().name("v11").teacherNum(1).studentNum(2).build();
        SchoolVO v12 = SchoolVO.builder().name("v12").teacherNum(1).studentNum(2).build();
        SchoolVOList = Arrays.asList(v9, v10, v11, v12);
        v5.setSubSchoolVOList(SchoolVOList);
        SchoolVO v13 = SchoolVO.builder().name("v13").teacherNum(1).studentNum(2).build();
        SchoolVO v14 = SchoolVO.builder().name("v14").teacherNum(1).studentNum(2).build();
        SchoolVOList = Arrays.asList(v13, v14);
        v11.setSubSchoolVOList(SchoolVOList);
        System.out.println(v0);
    }

2 service 调用各自的汇总方式

    //单独字段汇总
    @Override
    public SchoolVO treeStatisticsBySign(SchoolVO schoolVO) {
        statisticslBySign(schoolVO);
        return schoolVO;
    }

    //联合字段汇总
    @Override
    public SchoolVO tressStatisticsByOverall(SchoolVO schoolVO) {
        statisticsByOverall(schoolVO);
        return schoolVO;
    }

3 初始化的树形结构

四 输出结果(因树形层级比较多,结果只截图一部分)

1 单独汇总的结果(以汇总老师数量为例)

2  联合汇总的结果

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值