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

如何按Key分组HashMap元素并求和值?基于PartNatureDon模型实现

需求

需要按NatureDon对HashMap中的项进行分组,对重复项的金额求和,并将结果保存到PartNatureDon模型中。

实体类定义

public class PartNatureDon extends BaseEntity{

    @ManyToOne
    @JoinColumn(name = "nature_don_col_id", nullable = false)
    private NatureDon natureDon;

    @ManyToOne
    @JoinColumn(name = "assistance_col_id", nullable = false)
    private Assistance assistance;

    @Column
    private double montant;
}

现有代码(存在逻辑问题)

public void savePartNatureDon(){
    PartNatureDon partNatureDon = new PartNatureDon();
    Set<Don> dons = selected.getDons();

    List<NatureDon> natureDonList = new ArrayList<>();
    for (Don don : dons){
        partNatureDon.setAssistance(don.getAssistance());
        
        List<NatureDon> natureDons = don.getNatureDonList();
        HashMap<String, Double> montant = new HashMap<>();
        for (NatureDon natureDon : natureDons){

            if (!natureDonList.stream().anyMatch(n->n.getLibelle().equals(natureDon.getLibelle()))) {
                natureDonList.add(natureDon);

                natureDonList.forEach (natureDon1 -> {
                        montant.putIfAbsent(natureDon1.getLibelle(), Double.valueOf(don.getMontantNatureDon().get(natureDon1.getLibelle())));
                        montant.computeIfPresent(natureDon1.getLibelle(), (n, nature) -> Double.valueOf(nature + don.getMontantNatureDon().get(natureDon1.getLibelle())));
                });
            }

        }

    }
}

修正后的实现方案

现有代码存在逻辑混乱(如每次循环新建HashMap、重复遍历列表、未实现最终保存逻辑),以下是更简洁高效的实现,利用Java 8+ Stream API完成分组求和:

// 假设你已注入JPA Repository用于保存PartNatureDon
@Autowired
private PartNatureDonRepository partNatureDonRepository;

public void savePartNatureDon(){
    Set<Don> dons = selected.getDons();

    // 1. 按「Assistance + NatureDon」分组,累加对应金额
    Map<Assistance, Map<NatureDon, Double>> groupedData = dons.stream()
        .flatMap(don -> don.getNatureDonList().stream()
            .map(natureDon -> new AbstractMap.SimpleEntry<>(
                // 构建分组键:Assistance + NatureDon
                new AbstractMap.SimpleEntry<>(don.getAssistance(), natureDon),
                // 获取当前Don中该NatureDon的金额
                don.getMontantNatureDon().get(natureDon.getLibelle())
            ))
        )
        .collect(Collectors.groupingBy(
            entry -> entry.getKey().getKey(), // 外层按Assistance分组
            Collectors.groupingBy(
                entry -> entry.getKey().getValue(), // 内层按NatureDon分组
                Collectors.summingDouble(Map.Entry::getValue) // 求和金额
            )
        ));

    // 2. 将分组结果转换为PartNatureDon实体并保存
    List<PartNatureDon> partNatureDons = new ArrayList<>();
    groupedData.forEach((assistance, natureDonAmountMap) -> {
        natureDonAmountMap.forEach((natureDon, totalMontant) -> {
            PartNatureDon entity = new PartNatureDon();
            entity.setAssistance(assistance);
            entity.setNatureDon(natureDon);
            entity.setMontant(totalMontant);
            partNatureDons.add(entity);
        });
    });

    // 批量保存到数据库
    partNatureDonRepository.saveAll(partNatureDons);
}

实现说明

  • 分组逻辑:通过嵌套分组,先按Assistance分组,再按NatureDon分组,同时用summingDouble自动累加同一分组下的金额。
  • 数据转换:遍历分组后的结果,为每个「Assistance + NatureDon」组合创建PartNatureDon实体,设置对应的总金额。
  • 批量保存:使用saveAll批量插入,提升数据库操作效率。

内容的提问来源于stack exchange,提问作者Krah Landry Koffi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 19:00:31