如何填充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
相关产品推荐
相关产品推荐

