条件groupingBy分组:高级Java Streams复杂分组操作实现咨询
实现方案
这个需求可以完全通过Java Stream API实现,以下是具体实现思路和代码:
前置假设
- 你的实体类定义为
DataEntity,包含属性A、B、C、D、E、F、G、H(Integer类型)、I,均有对应的getter方法 - 以下示例兼容Java 8及以上版本,若使用Java 16+可改用
record定义分组Key,简化代码,避免字符串拼接冲突
核心实现代码
// 1. 完成一级分组,按A+B+C+D+I分组 Map<String, List<DataEntity>> firstLevelGroup = data.stream() .collect(Collectors.groupingBy(entity -> entity.getA() + "_" + entity.getB() + "_" + entity.getC() + "_" + entity.getD() + "_" + entity.getI() )); // 2. 按规则处理每个一级分组,得到最终结果 List<List<DataEntity>> finalGroups = firstLevelGroup.values().stream() .flatMap(group -> { // 判断当前分组内E属性是否有重复:去重后数量小于原分组大小即存在重复 long distinctECount = group.stream().map(DataEntity::getE).distinct().count(); if (distinctECount >= group.size()) { // 无重复E值,直接保留原分组 return Stream.of(group); } // 存在重复E值,触发二级分组:按F+G分组后合并H值 return group.stream() .collect(Collectors.groupingBy(entity -> entity.getF() + "_" + entity.getG() )) .values().stream() .map(subGroup -> { // 同F+G的子组合并H值,其他属性取子组第一个元素的值即可 DataEntity firstItem = subGroup.get(0); int sumH = subGroup.stream().mapToInt(DataEntity::getH).sum(); // 构造合并后的实体,根据你实际的构造方法调整即可 DataEntity mergedItem = new DataEntity(); mergedItem.setA(firstItem.getA()); mergedItem.setB(firstItem.getB()); mergedItem.setC(firstItem.getC()); mergedItem.setD(firstItem.getD()); mergedItem.setE(firstItem.getE()); mergedItem.setF(firstItem.getF()); mergedItem.setG(firstItem.getG()); mergedItem.setH(sumH); mergedItem.setI(firstItem.getI()); return Collections.singletonList(mergedItem); }); }) .collect(Collectors.toList());
结果说明
以上代码执行后,finalGroups就是你需要的最终分组集合:
- 原group1(obj1、obj2、obj3)因E值重复,拆分为2个分组:合并后的obj1+obj2(H值为14)、单独的obj3
- 原group2(obj4)无E值重复,保留为1个分组
总共3个分组,完全符合预期。
内容的提问来源于stack exchange,提问作者MFEB
相关产品推荐
相关产品推荐

