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

Java Stream按关联Product属性分组并统计quantity总和的实现咨询

前置要求

请确保你的三个实体类已实现对应属性的getter方法:

  • Product类实现getProductName()、getMeasurementUnit()
  • InwardOutwardList类实现getProduct()、getQuantity()
  • InwardInventory类实现getInwardOutwardList()

方案1:使用SimpleEntry作为分组键(兼容所有JDK8+版本)

import java.util.AbstractMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

// 此处替换为你实际的InwardInventory实例集合变量
List<InwardInventory> inwardInventoryList = ...;

Map<AbstractMap.SimpleEntry<String, String>, Double> quantitySumResult = inwardInventoryList.stream()
        // 打平所有InwardInventory下的出入库明细,得到所有InwardOutwardList实例流
        .flatMap(inwardInventory -> inwardInventory.getInwardOutwardList().stream())
        // 可选过滤:过滤掉product为空的异常数据,业务可保证非空时可删除
        .filter(entry -> entry.getProduct() != null)
        // 按(产品名、计量单位)分组,求和对应quantity
        .collect(Collectors.groupingBy(
                entry -> new AbstractMap.SimpleEntry<>(
                        entry.getProduct().getProductName(),
                        entry.getProduct().getMeasurementUnit()
                ),
                // quantity为null时按0计算,业务可保证非空时可简化为Collectors.summingDouble(InwardOutwardList::getQuantity)
                Collectors.summingDouble(entry -> entry.getQuantity() == null ? 0d : entry.getQuantity())
        ));

// 遍历结果示例
quantitySumResult.forEach((groupKey, sum) -> {
    String productName = groupKey.getKey();
    String measurementUnit = groupKey.getValue();
    System.out.printf("产品名:%s,计量单位:%s,总数量:%.2f%n", productName, measurementUnit, sum);
});

方案2:使用Record作为分组键(JDK16+推荐,可读性更高)

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

// 定义分组键的记录类,也可单独声明为公共类
record ProductGroup(String productName, String measurementUnit) {}

// 统计逻辑
List<InwardInventory> inwardInventoryList = ...;
Map<ProductGroup, Double> quantitySumResult = inwardInventoryList.stream()
        .flatMap(inwardInventory -> inwardInventory.getInwardOutwardList().stream())
        .filter(entry -> entry.getProduct() != null)
        .collect(Collectors.groupingBy(
                entry -> new ProductGroup(
                        entry.getProduct().getProductName(),
                        entry.getProduct().getMeasurementUnit()
                ),
                Collectors.summingDouble(entry -> entry.getQuantity() == null ? 0d : entry.getQuantity())
        ));

注意事项

  • 如果JDK版本低于16且不想用SimpleEntry,可自定义普通类作为分组键,重写equals()和hashCode()方法即可。
  • 如果需要保留更高精度,可将summingDouble替换为Collectors.reducing(BigDecimal.ZERO, entry -> BigDecimal.valueOf(entry.getQuantity() == null ? 0d : entry.getQuantity()), BigDecimal::add),同时将Map的value类型改为BigDecimal。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 17:09:00