集合转为树结构工具

表头

工具类

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;
        });
相关推荐
2401_873479402 小时前
运营活动被薅羊毛怎么防?用IP查询+设备指纹联动封堵漏洞
java·网络·tcp/ip·github
ShiJiuD6668889992 小时前
大事件板块一
java
摇滚侠2 小时前
@Autowired 和 @Resource 的区别
java·开发语言
SeaTunnel2 小时前
(八)收官篇 | 数据平台最后一公里:数据集成开发设计与上线治理实战
java·大数据·开发语言·白鲸开源
吴声子夜歌3 小时前
Java——线程的基本协作机制
java·线程协作
谙弆悕博士3 小时前
【附C++源码】从零开始实现 2048 游戏
java·c++·游戏·源码·项目实战·2048
独自归家的兔4 小时前
OCPP 1.6 协议详解:GetLocalListVersion 获取本地列表版本指令
java·后端·物联网·spring·ocpp1.6
Apache RocketMQ5 小时前
RocketMQ源码解析——秒级定时消息介绍
java·云原生·消息队列·rocketmq·java-rocketmq
xiaoming00185 小时前
JAVA项目打包部署运维全流程(多服务、批量)
java·linux·运维
拾-光6 小时前
【Git】命令大全:从入门到高手,100 个最常用命令速查(2026 版)
java·大数据·人工智能·git·python·elasticsearch·设计模式