如何基于Sample对象集合创建按货币分组并汇总金额的Map?
解决Sample集合转货币-金额总和Map的问题
嘿,我来帮你搞定这个问题!先拆解下你原来代码里的问题,再给你正确的实现方案。
原代码的核心问题
你的代码有两个明显的错误:
e.getAmount()无法调用.stream():Sample类的amount是单个String,不是集合或流对象,这行代码会直接编译失败,根本没法对单个字符串启动流操作。Collectors.toMap()不支持重复键:如果集合里有多个同货币类型的Sample对象,toMap会直接抛出IllegalStateException,因为它默认不允许键重复的情况。
正确的实现方式
我们需要用Collectors.groupingBy()按货币类型分组,再搭配Collectors.summingDouble()来计算每组的金额总和,同时要把String类型的amount转成数值类型:
import java.util.List; import java.util.Map; import java.util.stream.Collectors; class Sample { private String currency; private String amount; // 必须的构造方法与getter public Sample(String currency, String amount) { this.currency = currency; this.amount = amount; } public String getCurrency() { return currency; } public String getAmount() { return amount; } } public class CurrencySumDemo { public static void main(String[] args) { List<Sample> samples = List.of( new Sample("INR", "20"), new Sample("INR", "20"), new Sample("USD", "50"), new Sample("USD", "30"), new Sample("EUR", "20") ); Map<String, Double> finalResult = samples.stream() .collect(Collectors.groupingBy( Sample::getCurrency, Collectors.summingDouble(sample -> Double.parseDouble(sample.getAmount())) )); // 输出符合预期的结果:INR 40、USD 80、EUR 20 finalResult.forEach((currency, total) -> System.out.println(currency + " " + total.intValue())); } }
代码逻辑解释
Collectors.groupingBy(Sample::getCurrency):自动把所有Sample对象按货币类型分组,相同货币的对象会被归为一组。Collectors.summingDouble(...):对每组内的所有Sample,将amount字符串解析为Double后求和,最终结果作为该货币在Map中对应的值。
可选的异常处理
如果你的amount字段可能存在非数字的无效值,可以先过滤掉这些数据,避免运行时抛出NumberFormatException:
Map<String, Double> finalResult = samples.stream() .filter(sample -> { try { Double.parseDouble(sample.getAmount()); return true; } catch (NumberFormatException e) { // 可在此处记录日志,直接跳过无效数据 return false; } }) .collect(Collectors.groupingBy( Sample::getCurrency, Collectors.summingDouble(sample -> Double.parseDouble(sample.getAmount())) ));
内容的提问来源于stack exchange,提问作者Farrukh Chishti
相关产品推荐
相关产品推荐

