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

如何填充Map中List缺失的monthNumber字段并设置amount为0?

补全Map中缺失月份数据的实现方案

问题背景

我有一个Map对象,定义如下:

Map<Id, List<ExpenseController.MonthRow>> monthsPerKeeper = new Map<Id, List<ExpenseController.MonthRow>>();

当前仅包含有数据的月份(通过monthNumber标识),需要补全1-12月中所有缺失的月份,将缺失月份的amount字段设为0,最终每个Id对应的列表都包含完整的12个月份数据。

我尝试了以下代码但无法实现需求:

for (Id c : monthsPerKeeper.keySet()) {
            if(monthsPerKeeper.containsKey(c)) {
                for (ExpenseController.MonthRow a : monthsPerKeeper.get(c)) {
                    
                    List<ExpenseController.MonthRow> monthsListAdd = new List<ExpenseController.MonthRow>();
                    for (Integer i = 1; i < 13; i++)  {

                        if (!monthsPerKeeper.get(c).monthNumber.containsKey(i)) {
                            ExpenseController.MonthRow row = new ExpenseController.MonthRow();
                            row.monthName = ExpenseController.monthNumbers.get(i);
                            row.amount = 0;
                            row.monthNumber = i;

                            monthsListAdd.add(row);
                        }
                        
                    }
                }
            }
        }   

问题分析

你的代码存在几个核心问题:

  • 嵌套循环逻辑冗余:遍历已有MonthRow时重复创建补全列表,且未将补全的行合并到原列表中
  • 判断条件错误:monthsPerKeeper.get(c).monthNumber是无效调用,因为monthsPerKeeper.get(c)返回的是List,没有monthNumber属性,无法直接判断月份是否存在
  • 未处理列表顺序:补全后的数据没有按月份排序,可能导致展示顺序混乱

正确实现代码

for (Id keeperId : monthsPerKeeper.keySet()) {
    // 获取当前Id对应的月份列表
    List<ExpenseController.MonthRow> monthRows = monthsPerKeeper.get(keeperId);
    // 存储已存在的月份编号,快速判断是否缺失
    Set<Integer> existingMonthNums = new Set<Integer>();

    // 提取已有月份的编号到Set中
    for (ExpenseController.MonthRow row : monthRows) {
        existingMonthNums.add(row.monthNumber);
    }

    // 遍历1-12月,补全缺失月份
    for (Integer num = 1; num <= 12; num++) {
        if (!existingMonthNums.contains(num)) {
            ExpenseController.MonthRow newRow = new ExpenseController.MonthRow();
            newRow.monthNumber = num;
            newRow.monthName = ExpenseController.monthNumbers.get(num);
            newRow.amount = 0;
            monthRows.add(newRow);
        }
    }

    // 按月份编号排序,确保1-12月顺序展示
    monthRows.sort((rowA, rowB) -> rowA.monthNumber - rowB.monthNumber);
    // 更新Map(List是引用类型,此步骤可省略,显式更新更清晰)
    monthsPerKeeper.put(keeperId, monthRows);
}

关键细节说明

  • 使用Set优化判断效率:将已有月份编号存入Set<Integer>,可以在O(1)时间内判断月份是否存在,比遍历List判断的O(n)效率更高
  • 直接操作原列表:补全的月份行直接添加到原列表中,无需额外创建临时列表再合并,简化逻辑
  • 排序保证展示顺序:通过Lambda表达式对列表按monthNumber升序排序,确保最终列表按1月到12月的顺序排列,符合预期展示效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 23:41:29