如何使用Java 8 Stream一行代码实现按字段分组并对指定字段求和
使用Java 8 Stream按支付码统计收款总金额
你现在的代码已经完成了按paymentCode分组的第一步,但其实完全不需要先把金额收集成列表——Java 8的Collectors工具类已经提供了直接求和的下游收集器,一步就能得到每个支付码对应的总金额。
只需要把你当前代码里的Collectors.mapping(Payment::getAmount, Collectors.toList())替换成Collectors.summingInt(Payment::getAmount)就可以了。summingInt会自动遍历每个分组里的Payment对象,提取amount字段并累加求和,省去了手动处理列表的步骤。
修改后的核心代码
Map<String, Integer> paymentSumByCode = payments.stream() .collect(Collectors.groupingBy(Payment::getPaymentCode, Collectors.summingInt(Payment::getAmount)));
完整可运行代码
import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; class Payment { Integer txnId; String paymentCode; Integer amount; Payment(Integer txnId, String paymentCode, Integer amount) { this.txnId = txnId; this.paymentCode = paymentCode; this.amount = amount; } public String getPaymentCode() { return this.paymentCode; } public Integer getAmount() { return this.amount; } @Override public String toString() { return "Payment [txnId=" + txnId + ", paymentCode=" + paymentCode + ", amount=" + amount + "]"; } } public class ListGroupingSum { public static void main(String[] args) { List<Payment> payments = new ArrayList<>(); payments.add(new Payment(100, "GPAY", 100)); payments.add(new Payment(101, "CC", 200)); payments.add(new Payment(102, "PAYTM", 300)); payments.add(new Payment(103, "GPAY", 400)); payments.add(new Payment(104, "CC", 500)); // 直接分组并计算总金额 Map<String, Integer> paymentSumByCode = payments.stream() .collect(Collectors.groupingBy(Payment::getPaymentCode, Collectors.summingInt(Payment::getAmount))); System.out.println(paymentSumByCode); } }
运行后输出就是你期望的结果:{CC=700, GPAY=500, PAYTM=300}
另外补充下,如果你的金额字段是Long或Double类型,对应可以用Collectors.summingLong或Collectors.summingDouble,这些都是专门为数值聚合设计的收集器,比先转列表再手动求和高效得多。
内容的提问来源于stack exchange,提问作者Satish Patro
相关产品推荐
相关产品推荐

