Java8实现分组求和

由于的美国的制裁,加速了国内很多公司产品构成去美化进程,而在软件行业的数据库层面,越来越多的公司进行去Oracle化。本人所在公司有自研内存数据库,聚合函数的支持初期没那么完善,有时一部分逻辑要从数据库转化到java实现,今天举一个java实现分组求和来代替数据库聚合函数sum()+group by的栗子


分组求和


举一个生产过程的引用例子,代码如下:

/**
 * @Description //TODO 根据客户列表查欠费信息
 * @Date: 2021/7/15
 **/
public List<UnPayBillDTO> getUnPayInfo(List<Long> contractNoList,String yearMonth){

    List<UnPayBillDTO> unPayBillDTOList = new ArrayList<>(); // 结果集

    for (long contractNo : contractNoList) {

        ActUnpayoweInfo actUnpayoweInfoParam = new ActUnpayoweInfo();
        actUnpayoweInfoParam.setContractNo(contractNo);
        List<ActUnpayoweInfo> actUnpayoweInfos = actUnpayoweInfoMapper.select(actUnpayoweInfoParam); // 该账户所有欠费信息

        /* 分组 */
        Map<String,List<ActUnpayoweInfo>> afterGroupMap
                = actUnpayoweInfos.stream().
                filter(o -> o.getNaturalMonth().equals(yearMonth)). // 过滤掉当月欠费
                        collect(Collectors.groupingBy(o -> o.getContractNo() + "_" + o.getNaturalMonth() + "_" + o.getAcctItemCode()));

        afterGroupMap.forEach(
            (group, groupInfo) -> {

                /* 获取分组字段 */
                String[] tmpInfo = group.split("_");
                long tmpContractNo = Long.parseLong(tmpInfo[0]);
                String tmpNaturalMonth = tmpInfo[1];
                String tmpAcctItemCode = tmpInfo[2];

                /* 求和 */
                long totalMoney = groupInfo.stream().mapToLong(this::calculate).sum();

                UnPayBillDTO unPayBillDTO = new UnPayBillDTO();
                unPayBillDTO.setContractNo(tmpContractNo);
                unPayBillDTO.setNaturalMonht(tmpNaturalMonth);
                unPayBillDTO.setAcctItemCode(tmpAcctItemCode);
                unPayBillDTO.setTotalMoney(totalMoney);

                unPayBillDTOList.add(unPayBillDTO);

            }
        );
    }
    return unPayBillDTOList;
}


分组

分组是先利用stream进行遍历,然后以group by涉及的字段进行拼接,作为Collector进行分组的条件,最终返回一个以分组条件拼接的字符串作为key值,分好组的各个对应list作为value的map;

Map<String,List<ActUnpayoweInfo>> afterGroupMap
	= actUnpayoweInfos.stream().
		filter(o -> o.getNaturalMonth().equals(yearMonth)). // 过滤掉当月欠费
			collect(Collectors.groupingBy(o -> o.getContractNo() + "_" + o.getNaturalMonth() + "_" + o.getAcctItemCode()));

求和

对每一组进行处理,从key值获取分组条件信息,对value值里面的多条数据相关字段进行计算后累加求和

/* 获取分组字段 */
String[] tmpInfo = group.split("_");
long tmpContractNo = Long.parseLong(tmpInfo[0]);
String tmpNaturalMonth = tmpInfo[1];
String tmpAcctItemCode = tmpInfo[2];

/* 求和 */
long totalMoney = groupInfo.stream().mapToLong(this::calculate).sum();

this::calculate 是涉及业务的一些计算,这里不做展开

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值