Java Streams如何按字段匹配汇总零件数量?
问题解决:按零件编号去重并汇总数量
需求说明
现有Part对象列表示例:
Part("12345" , "Part1", 5)); Part("67890" , "Part5", 2)); Part("12345" , "Part1", 2));
需要转换为按零件编号去重、对应数量求和的列表,预期结果:
Part("12345" , "Part1", 7)); Part("67890" , "Part5", 2));
修改后的代码实现
你原来的代码仅做了对象复制,未实现分组求和逻辑。正确做法是先通过分组聚合相同编号的零件,再汇总数量,最后转换回Part对象列表:
return emptyIfNull(partList.getParts()) .stream() // 按零件编号分组,同时汇总每组的数量 .collect(Collectors.groupingBy( Part::getNumber, Collectors.summarizingInt(Part::getQuantity) )) .entrySet() .stream() .map(entry -> { // 从原列表中获取对应编号零件的描述(假设同编号描述一致) String desc = emptyIfNull(partList.getParts()) .stream() .filter(p -> p.getNumber().equals(entry.getKey())) .findFirst() .map(Part::getDescription) .orElse(null); return Part.builder() .partNumber(entry.getKey()) .partDescription(desc) .partQuantity(entry.getValue().getSum()) .build(); }) .collect(Collectors.toList());
简化优化(保证同编号描述一致时)
如果能确定同一零件编号对应的描述完全相同,可以用更简洁的toMap实现:
return emptyIfNull(partList.getParts()) .stream() .collect(Collectors.toMap( Part::getNumber, part -> part, // 重复编号时合并:保留描述,数量求和 (existing, newPart) -> Part.builder() .partNumber(existing.getNumber()) .partDescription(existing.getDescription()) .partQuantity(existing.getQuantity() + newPart.getQuantity()) .build() )) .values() .stream() .collect(Collectors.toList());
关键逻辑说明
Collectors.groupingBy:以零件编号为key,将相同编号的零件归为一组Collectors.summarizingInt:对每组内的quantity字段求和,返回包含总和的统计对象Collectors.toMap:直接用编号作为key,遇到重复key时执行合并逻辑,实现数量累加- 若存在同编号描述不一致的场景,需额外处理(如抛出异常、取第一个描述等)
内容的提问来源于stack exchange,提问作者user21355134
相关产品推荐
相关产品推荐

