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

如何对Map<String, List<Records>>同Key的Records属性累乘并转Map<String, Records>

解决Map中同Key下Records属性累乘的问题

定义的Records类

public class Records { 
    private BigDecimal price;
    private BigDecimal tos;
    private BigDecimal share;
    
    // 必须补充以下getter/setter方法,否则代码无法正常访问/修改属性
    public BigDecimal getPrice() { return price; }
    public void setPrice(BigDecimal price) { this.price = price; }
    public BigDecimal getTos() { return tos; }
    public void setTos(BigDecimal tos) { this.tos = tos; }
    public BigDecimal getShare() { return share; }
    public void setShare(BigDecimal share) { this.share = share; }
}

需求说明

现有Map<String, List<Records>>集合,每个Key对应一组Records对象,需对同一Key下所有Records的price、share、tos属性分别执行累乘操作,最终生成每个Key对应单个Records实例的Map<String, Records>。

示例数据

输入

{
"Id1": [ { "price": 3, "share": 4, "tos": 5}, { "price": 2, "share": 3, "tos": 6} ],
"Id2": [ { "price": 1, "share": 7, "tos": 4} ]
}

期望输出

{
"Id1": { "price": 6, "share": 12, "tos": 30},
"Id2": { "price": 1, "share": 7, "tos": 4}
}

原代码的问题分析

你提供的代码存在以下关键问题:

  • recordData未初始化,直接调用put会抛出NullPointerException
  • 嵌套循环逻辑混乱:外层已遍历entrySet,内层又遍历keySet,导致重复处理且关联关系错误
  • 未处理列表大小为1的情况:此时output的属性会为null,不符合期望输出
  • 变量作用域不合理:output在循环中重复创建,但未正确绑定到当前Key

修正后的实现方案

方案1:传统循环实现

private static Map<String, Records> getCumulativeSafFafPaf(Map<String, List<Records>> recordsMap) {
    // 初始化结果Map,避免空指针
    Map<String, Records> recordData = new HashMap<>();

    for (Map.Entry<String, List<Records>> entry : recordsMap.entrySet()) {
        String key = entry.getKey();
        List<Records> recordsList = entry.getValue();

        Records resultRecord = new Records();
        // 初始化累乘初始值为1,兼容列表大小为1的场景
        BigDecimal totalPrice = BigDecimal.ONE;
        BigDecimal totalShare = BigDecimal.ONE;
        BigDecimal totalTos = BigDecimal.ONE;

        for (Records record : recordsList) {
            // 对每个属性执行累乘,并处理精度
            totalPrice = DecimalUtil.resetValueWithDefaultScale(totalPrice.multiply(record.getPrice()));
            totalShare = DecimalUtil.resetValueWithDefaultScale(totalShare.multiply(record.getShare()));
            totalTos = DecimalUtil.resetValueWithDefaultScale(totalTos.multiply(record.getTos()));
        }

        // 设置累乘后的属性值
        resultRecord.setPrice(totalPrice);
        resultRecord.setShare(totalShare);
        resultRecord.setTos(totalTos);

        // 将结果存入Map,绑定当前Key
        recordData.put(key, resultRecord);
    }

    return recordData;
}

方案2:Java Stream流实现(Java 8+)

如果偏好更简洁的代码,可以用Stream的reduce操作实现累乘:

private static Map<String, Records> getCumulativeSafFafPaf(Map<String, List<Records>> recordsMap) {
    return recordsMap.entrySet().stream()
            .collect(Collectors.toMap(
                    Map.Entry::getKey,
                    entry -> {
                        Records resultRecord = new Records();
                        // 对price属性累乘
                        BigDecimal totalPrice = entry.getValue().stream()
                                .map(Records::getPrice)
                                .reduce(BigDecimal.ONE, (a, b) -> DecimalUtil.resetValueWithDefaultScale(a.multiply(b)));
                        // 对share属性累乘
                        BigDecimal totalShare = entry.getValue().stream()
                                .map(Records::getShare)
                                .reduce(BigDecimal.ONE, (a, b) -> DecimalUtil.resetValueWithDefaultScale(a.multiply(b)));
                        // 对tos属性累乘
                        BigDecimal totalTos = entry.getValue().stream()
                                .map(Records::getTos)
                                .reduce(BigDecimal.ONE, (a, b) -> DecimalUtil.resetValueWithDefaultScale(a.multiply(b)));
                        
                        resultRecord.setPrice(totalPrice);
                        resultRecord.setShare(totalShare);
                        resultRecord.setTos(totalTos);
                        return resultRecord;
                    }
            ));
}

关键注意点

  • 确保Records类有完整的getter和setter方法,否则无法正常访问和修改属性
  • DecimalUtil.resetValueWithDefaultScale方法需保证正确处理BigDecimal的精度问题,避免出现无限小数或精度丢失
  • 累乘初始值设为BigDecimal.ONE,确保单元素列表的结果与原属性值一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 22:01:16