如何使用Java Streams按typeId计算Charge对象的平均值
嘿,这就帮你搞定这个需求!咱们完全用Java Streams API实现,全程不用for或forEach循环,完美符合要求。
实现代码
public Bill average(List<Bill> bills) { List<Charge> averageCharges = bills.stream() // 把所有Bill里的Charge扁平化,变成一个连续的Charge流 .flatMap(bill -> bill.getCharges().stream()) // 按typeId分组,同时对每个分组的Charge计算a、b的平均值 .collect(Collectors.groupingBy( Charge::getTypeId, Collectors.collectingAndThen( Collectors.toList(), charges -> { // 计算a的平均值,orElse(0.0)处理空分组的边界情况 double avgA = charges.stream() .mapToDouble(Charge::getA) .average() .orElse(0.0); // 同理计算b的平均值 double avgB = charges.stream() .mapToDouble(Charge::getB) .average() .orElse(0.0); // 返回对应typeId的平均Charge对象 return new Charge(charges.get(0).getTypeId(), avgA, avgB); } ) )) // 提取分组后的所有平均Charge,转为列表 .values() .stream() .collect(Collectors.toList()); // 构造并返回id为null的Bill对象 return new Bill(null, averageCharges); }
思路拆解
- 扁平化处理:用
flatMap把每个Bill内部的List<Charge>展开成一个统一的Stream<Charge>,这样就能一次性处理所有Charge数据。 - 按typeId分组统计:通过
groupingBy按typeId分组,再用collectingAndThen对每个分组的Charge列表做后续处理——计算a、b字段的平均值,生成对应的平均Charge对象。 - 收集结果并构造Bill:把分组后的平均Charge收集成列表,最后创建一个
id为null的Bill对象返回。
这个实现完全遵循要求,没有使用任何显式循环,全程依赖Streams的链式操作完成数据处理。
内容的提问来源于stack exchange,提问作者Syed Zishan
相关产品推荐
相关产品推荐

