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
是涉及业务的一些计算,这里不做展开
public long calculate(ActUnpayoweInfo actUnpayoweInfo){
return actUnpayoweInfo.getShouldPay() - actUnpayoweInfo.getFavourFee() - actUnpayoweInfo.getPayedLater() - actUnpayoweInfo.getPayedPrepay();
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)