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

Java7/Java8按产品ID汇总销售数据的实现问题

按ID汇总Product的price与quantity总和问题解决

原代码问题点

你当前的Stream代码只完成了按ID汇总price总和的逻辑,既没有处理quantity的累加,而且返回的Map<Integer, Double>只能存储ID和总价,丢失了name和总数量的信息,这和你需要的完整汇总结果完全不符。

可行解决方案

方案1:自定义汇总结果类

如果不想改动原Product类,可以新建一个专门存汇总数据的类:

// 汇总结果实体类
class ProductSummary {
    private int id;
    private String name;
    private double totalPrice;
    private int totalQuantity;

    // 构造方法
    public ProductSummary(int id, String name, double totalPrice, int totalQuantity) {
        this.id = id;
        this.name = name;
        this.totalPrice = totalPrice;
        this.totalQuantity = totalQuantity;
    }

    // 合并方法:用于累加同一ID的价格和数量
    public ProductSummary merge(Product product) {
        this.totalPrice += product.getPrice();
        this.totalQuantity += product.getQuantity();
        return this;
    }

    // 重写toString方便输出结果
    @Override
    public String toString() {
        return id + ", " + name + ", " + totalPrice + ", " + totalQuantity;
    }
}

接着用Collectors.toMap实现分组合并:

// 执行汇总并转成列表
List<ProductSummary> result = new ArrayList<>(products.stream()
        .collect(Collectors.toMap(
                Product::getId, // 分组键:Product的ID
                p -> new ProductSummary(p.getId(), p.getName(), p.getPrice(), p.getQuantity()), // 初始值:用当前Product创建汇总对象
                ProductSummary::merge // 合并规则:同一ID的对象累加价格和数量
        ))
        .values());

// 打印预期结果
result.forEach(System.out::println);

方案2:直接复用原Product类

如果原Product类支持修改属性(有setter方法)或者有对应构造方法,可以直接用原类存储汇总结果:

List<Product> result = new ArrayList<>(products.stream()
        .collect(Collectors.toMap(
                Product::getId,
                p -> new Product(p.getId(), p.getName(), p.getPrice(), p.getQuantity()), // 初始对象
                (existingProd, newProd) -> {
                    // 累加价格和数量
                    existingProd.setPrice(existingProd.getPrice() + newProd.getPrice());
                    existingProd.setQuantity(existingProd.getQuantity() + newProd.getQuantity());
                    return existingProd;
                }
        ))
        .values());

// 输出结果
result.forEach(p -> System.out.printf("%d, %s, %.0f, %d%n", p.getId(), p.getName(), p.getPrice(), p.getQuantity()));

原代码逻辑拆解

你原代码里的Collectors.summarizingDouble(Product::getPrice)只是生成了price的统计信息(总和、均值、最值等),再通过collectingAndThen只提取了总和,所以最终只能得到ID对应总价的Map,完全没处理quantity的累加,也没保留name信息,这就是结果不符合预期的核心原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 14:36:05