You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Stream Collect实现同名对象数量求和(避免使用toMap)

替代Collectors.toMap实现InventoryDetail按name汇总quantity的方案及ClassCastException排查

一、无需toMap的汇总实现方案

可以通过Collectors.groupingBy配合summingInt先按name分组并求和,再将分组结果转换为目标InventoryDetail列表,代码如下:

// 原始数据示例
List<InventoryDetail> originalDetails = Arrays.asList(
    new InventoryDetail("iPhone", 2),
    new InventoryDetail("iPhone", 2),
    new InventoryDetail("Samsung", 1),
    new InventoryDetail("Nokia", 1),
    new InventoryDetail("Motorolla", 1)
);

// 汇总逻辑
List<InventoryDetail> summedDetails = originalDetails.stream()
    // 按name分组,同时对每组的quantity求和
    .collect(Collectors.groupingBy(
        InventoryDetail::getName,
        Collectors.summingInt(InventoryDetail::getQuantity)
    ))
    // 将分组的键值对转换为InventoryDetail对象
    .entrySet()
    .stream()
    .map(entry -> new InventoryDetail(entry.getKey(), entry.getValue()))
    .collect(Collectors.toList());

执行后即可得到预期的汇总结果:

[InventoryDetail(name=iPhone, quantity=4), InventoryDetail(name=Samsung, quantity=1), InventoryDetail(name=Nokia, quantity=1), InventoryDetail(name=Motorolla, quantity=1)]

二、自定义Collector抛出ClassCastException的常见原因

自定义Collector时出现类型转换异常,通常是以下几种情况导致:

  • 泛型参数不匹配:Collector的泛型参数(Supplier、Accumulator、Combiner、Finisher)定义错误,比如将累加器的容器类型声明为InventoryDetail,但实际用了Map<String, Integer>,导致后续强制转换失败。
  • 合并逻辑类型错误:Combiner函数中尝试将两个不兼容的类型合并,比如把单个InventoryDetail对象当成Map来合并,触发类型转换异常。
  • Finisher返回类型不符:Finisher函数返回的类型与Collector声明的输出类型不一致,比如声明输出List<InventoryDetail>,但实际返回了Map,强制转换时抛出异常。

举个典型错误示例:如果自定义Collector时错误地将累加器容器设为InventoryDetail,但实际需要用Map来存分组求和结果,就会在累加或合并阶段抛出ClassCastException。

内容的提问来源于stack exchange,提问作者Ramkumar SP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 15:16:12