
本文介绍使用 Java 8 Stream API 对对象列表按指定字段(如 range)分组,合并重复项并对其数值属性(如 contrast)执行求和操作的完整实现方法。
本文介绍使用 java 8 stream api 对对象列表按指定字段(如 `range`)分组,合并重复项并对其数值属性(如 `contrast`)执行求和操作的完整实现方法。
在实际开发中,常需对一组具有相同分类标识(如时间区间、类别名、ID 等)的对象进行聚合处理——保留唯一键,同时将对应数值字段(如计数、金额、权重等)累加。以 ContrastItem 类为例,其包含 range(字符串标识)和 contrast(长整型数值)两个属性,目标是:按 range 合并重复项,并将所有同 range 的 contrast 值求和。
核心思路分为三步:
-
分组:使用
Collectors.groupingBy按getRange()分组; -
聚合:嵌套
Collectors.summingLong对getContrast()求和,得到Map<string long></string>; -
重构:将
Map.Entry<string long></string>流式转换为新的ContrastItem实例列表。
以下是完整可运行示例(含构造函数支持):
public class ContrastItem {
private String range;
private Long contrast;
// 必须提供带参构造函数,便于后续映射重建
public ContrastItem(String range, Long contrast) {
this.range = range;
this.contrast = contrast;
}
// getter 方法(省略 setter,仅需读取)
public String getRange() { return range; }
public Long getContrast() { return contrast; }
@Override
public String toString() {
return String.format("{\"range\":\"%s\",\"contrast\":%d}", range, contrast);
}
}
主逻辑代码如下:
List<contrastitem> itemList = List.of(
new ContrastItem("00:00:00-00:59:59", 3L),
new ContrastItem("00:00:00-00:59:59", 1L),
new ContrastItem("01:00:00-01:59:59", 0L),
new ContrastItem("01:00:00-01:59:59", 0L)
);
List<contrastitem> merged = itemList.stream()
.collect(Collectors.groupingBy(
ContrastItem::getRange,
Collectors.summingLong(ContrastItem::getContrast)
))
.entrySet().stream()
.map(entry -> new ContrastItem(entry.getKey(), entry.getValue()))
.collect(Collectors.toList());
// 输出:[{"range":"00:00:00-00:59:59","contrast":4}, {"range":"01:00:00-01:59:59","contrast":0}]
System.out.println(merged);</contrastitem></contrastitem>
✅ 关键注意事项:
-
ContrastItem必须提供接受range和contrast的构造函数,否则map()阶段无法实例化新对象; - 若
contrast可能为null,建议改用Collectors.summingLong(item -> Optional.ofNullable(item.getContrast()).orElse(0L))避免空指针; - 如需保持原始顺序(如按首次出现的
range排序),可改用LinkedHashMap:.collect(Collectors.groupingBy(ContrastItem::getRange, LinkedHashMap::new, Collectors.summingLong(ContrastItem::getContrast)))
该方案简洁、函数式、无副作用,是 Java 8+ 处理“分组-聚合-重建”类需求的标准实践。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











