集合转为树结构工具

表头

工具类

java 复制代码
public class ThreeUtils {


    /**
     * 树结构转换处理-每次递归查询全部下级以及下级的子集
     *
     * @param menuList     需要处理的数据集
     * @param threeResult  返回对象
     * @param parentId     父级ID
     * @param dataTreating 逻辑处理
     * @param <T>
     */
    public static <T extends Three, E extends Three> void treeListAncestral(List<T> menuList, E threeResult, Long parentId, ThreeFunctional<T, E> dataTreating) {
        if (ObjectUtil.isEmpty(menuList)) {
            return;
        }
        Map<Long, List<T>> collect = menuList.stream().filter(menu -> menu != null && menu.getParentId() != null).collect(Collectors.groupingBy(Three::getParentId));
        //根据父级ID查询下级
        List<T> threes = collect.get(parentId);
        if (ObjectUtil.isEmpty(threes)) {
            return;
        }
        ArrayList<T> groupT = threes.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(T::getId))), ArrayList::new));
        for (T three : groupT) {
            /*根据本次循环ID查询所有下级以及子集*/
            List<T> ancestralThreeList = menuList.stream().filter(m -> StringUtil.leftPad(String.valueOf(m.getId()), String.valueOf(m.getId()).length()).equals(String.valueOf(three.getId()))).collect(Collectors.toList());
            if (ObjectUtil.isEmpty(ancestralThreeList)) {
                continue;
            }
            //树处理逻辑
            E e = dataTreating.dataTreating(ancestralThreeList, threeResult);
            if (null == e) {
                return;
            }
            /*创建下级返回对象类,并且存入当前上级的下级集合中*/
            List<E> itemList = threeResult.getItemList();
            if (null == itemList) {
                itemList = new ArrayList<>();
            }
            itemList.add(e);
            threeResult.setItemList(itemList);
            //执行递归处理
            treeListAncestral(menuList, e, three.getId(), dataTreating);
        }
    }


    /**
     * 树结构转换处理-每次递归查询下级
     *
     * @param menuList     树处理集合
     * @param threeResult  返回对象
     * @param parentId     父级ID
     * @param dataTreating 逻辑处理
     * @param <T>
     */
    public static <T extends Three, E extends Three> void treeList(List<T> menuList, E threeResult, Long parentId, ThreeFunctional<T, E> dataTreating) {
        if (ObjectUtil.isEmpty(menuList)) {
            return;
        }
        Map<Long, List<T>> collect = menuList.stream().filter(menu -> menu != null && menu.getParentId() != null).collect(Collectors.groupingBy(Three::getParentId));
        //根据父级ID查询下级
        List<T> threes = collect.get(parentId);
        if (ObjectUtil.isEmpty(threes)) {
            return;
        }
        ArrayList<T> groupT = threes.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(T::getId))), ArrayList::new));
        for (T three : groupT) {
            /*根据本次循环ID查询所有下级*/
            List<T> ancestralThreeList = menuList.stream().filter(menu -> menu != null && menu.getParentId() != null && menu.getParentId().equals(three.getId())).collect(Collectors.toList());
            if (ObjectUtil.isEmpty(ancestralThreeList)) {
                continue;
            }
            //树处理逻辑
            E e = dataTreating.dataTreating(ancestralThreeList, threeResult);
            if (null == e) {
                return;
            }
            /*创建下级返回对象类,并且存入当前上级的下级集合中*/
            List<E> itemList = threeResult.getItemList();
            if (null == itemList) {
                itemList = new ArrayList<>();
            }
            itemList.add(e);
            threeResult.setItemList(itemList);
            //执行递归处理
            treeList(menuList, e, three.getId(), dataTreating);
        }
    }
}

树处理函数接口

java 复制代码
@FunctionalInterface
public interface ThreeFunctional<T, E> {

    /**
     * 树处理逻辑
     *
     * @param threeList 处理后的树结构
     * @param data      处理后的树类结果对象
     *                  这里返回创建一个新的空对象即可
     */
    E dataTreating(List<T> threeList, E data);
}

树实体类

java 复制代码
@Data
public class Three<E> implements Serializable {
    private static final long serialVersionUID = 2883288479291688378L;

    private Long id;

    private String name;

    private Long parentId;

    //数据结果集
    private List<E> ItemList;

}

请求响应实体类

java 复制代码
@Data
@ApiModel("返回VO")
public class CoveredCountyEnteringVO extends Three<CoveredCountyEnteringVO> implements Serializable {
    private static final long serialVersionUID = -1571960669989120842L;

    private Integer monitorBabyNumber;

    private Integer standardBabyNumber;

    private BigDecimal percentOfPass;

}

@Data
@ApiModel("响应DTO")
public class CoveredCountyEnteringDTO extends Three<CoveredCountyEnteringDTO> implements Serializable {
    private static final long serialVersionUID = -1571960669989120842L;

    private String medicalQuestion1;


    private String medicalQuestion3;

    private String medicalQuestion7;


}

调用

java 复制代码
  //需要处理的数据集合-需要继承 Three类
        List<CoveredCountyEnteringDTO> questionnaireList = cniQuestionnaireMapper.selectByAreaCode(reportFormsDTO);
        //创建返回对象-继承 Three类
        CoveredCountyEnteringVO countyEnteringVO = new CoveredCountyEnteringVO();

        ThreeUtils.treeListAncestral(questionnaireList, countyEnteringVO, reportFormsDTO.getAreaCode(), (threeList, data) -> {
            if (ObjectUtil.isEmpty(threeList)) {
                return null;
            }
            Long monitorBabyNumber = threeList.stream().count();
            Stream<CoveredCountyEnteringDTO> standardBabyNumber = threeList.stream().filter(coveredCountyEnteringDTO -> null != coveredCountyEnteringDTO
                    && StringUtils.isNotBlank(coveredCountyEnteringDTO.getMedicalQuestion1())
                    && StringUtils.isNotBlank(coveredCountyEnteringDTO.getMedicalQuestion3())
                    && StringUtils.isNotBlank(coveredCountyEnteringDTO.getMedicalQuestion7()));

            CoveredCountyEnteringDTO coveredCountyEnteringDTO = threeList.get(0);
            /*将处理后的数据放入 data集合中*/
            CoveredCountyEnteringVO resultCoveredCountVO = new CoveredCountyEnteringVO();
            resultCoveredCountVO.setId(coveredCountyEnteringDTO.getId());
            resultCoveredCountVO.setName(coveredCountyEnteringDTO.getName());
            resultCoveredCountVO.setParentId(coveredCountyEnteringDTO.getParentId());

            resultCoveredCountVO.setMonitorBabyNumber(null != monitorBabyNumber ? Integer.valueOf(monitorBabyNumber + "") : 0);
            resultCoveredCountVO.setStandardBabyNumber(ObjectUtil.isNotEmpty(standardBabyNumber) ? Integer.valueOf(standardBabyNumber.count() + "") : 0);
            /*计算合格率*/
            resultCoveredCountVO.setPercentOfPass(BigDecimalUtils.rate(resultCoveredCountVO.getStandardBabyNumber() + "", resultCoveredCountVO.getMonitorBabyNumber() + ""));
            return resultCoveredCountVO;
        });
相关推荐
xiao--xin13 分钟前
LeetCode100之二叉搜索树中第K小的元素(230)--Java
java·算法·leetcode·二叉树·树的统一迭代法
钢板兽24 分钟前
Java后端高频面经——Spring、SpringBoot、MyBatis
java·开发语言·spring boot·spring·面试·mybatis
钢板兽30 分钟前
Java后端高频面经——JVM、Linux、Git、Docker
java·linux·jvm·git·后端·docker·面试
awonw1 小时前
[java][基础] 悲观锁 vs 乐观锁
java·开发语言
嘵奇1 小时前
10个实用IntelliJ IDEA插件
java·ide·intellij-idea
Trouvaille ~1 小时前
【Java篇】数据类型与变量:窥见程序的天地万象
java·开发语言·青少年编程·面向对象·数据类型·基础知识·入门必看
A仔不会笑1 小时前
MySQL面试篇——性能优化
java·数据库·mysql·面试·性能优化
用户53866168248221 小时前
SpringBoot 业务中 通过嵌套异步的方式 提高业务表数据同步效率
java·spring boot
MickeyCV1 小时前
《苍穹外卖》SpringBoot后端开发项目重点知识整理(DAY1 to DAY3)
java·spring boot·后端·苍穹外卖
雷渊1 小时前
深入分析mysql中的binlog和redo log
java·后端·面试