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
相关产品推荐
相关产品推荐

