如何在Java中为Map<Integer, Long>生成月度滚动累计数据
没问题,我来给你两种实现方式,一种用Java Stream优雅处理,另一种是更直观的传统循环,都能搞定这个月度滚动累计的需求:
方法一:Java Stream实现
这种方式利用Stream的排序和收集器,同时保证结果的顺序性:
import java.util.*; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; public class MonthCumulativeDemo { public static void main(String[] args) { // 模拟你的原始数据 Map<Integer, Long> monthCaseCountMap = new HashMap<>(); monthCaseCountMap.put(202103, 2L); monthCaseCountMap.put(202104, 4L); monthCaseCountMap.put(202105, 0L); monthCaseCountMap.put(202106, 9L); monthCaseCountMap.put(202202, 10L); // 初始化累计值容器 AtomicLong cumulativeSum = new AtomicLong(0); // 生成滚动累计Map Map<Integer, Long> cumulativeMap = monthCaseCountMap.entrySet() .stream() // 按月份键升序排序,确保时间顺序正确 .sorted(Map.Entry.comparingByKey()) .collect(Collectors.toMap( Map.Entry::getKey, // 累加当前月份的案例数,返回累计后的值 entry -> cumulativeSum.addAndGet(entry.getValue()), // 键重复时的合并逻辑(这里不会触发,因为月份键唯一) (oldVal, newVal) -> newVal, // 使用LinkedHashMap保持排序后的顺序 LinkedHashMap::new )); // 打印结果 cumulativeMap.forEach((month, count) -> System.out.printf("%d, %d%n", month, count)); } }
代码说明:
- 先对原始Map的entry按月份键排序,确保从最早到最晚的时间顺序处理;
- 用
AtomicLong维护累计值,因为Stream的Lambda表达式无法修改外部普通可变变量,原子类是安全的选择; - 最后用
LinkedHashMap收集结果,保证输出的Map和时间顺序一致。
方法二:传统循环实现
如果觉得Stream不够直观,这种方式更易懂,也方便调试:
import java.util.*; public class MonthCumulativeDemo { public static void main(String[] args) { Map<Integer, Long> monthCaseCountMap = new HashMap<>(); monthCaseCountMap.put(202103, 2L); monthCaseCountMap.put(202104, 4L); monthCaseCountMap.put(202105, 0L); monthCaseCountMap.put(202106, 9L); monthCaseCountMap.put(202202, 10L); // 用于保存累计结果,保持顺序 Map<Integer, Long> cumulativeMap = new LinkedHashMap<>(); long cumulativeSum = 0; // 获取排序后的月份列表 List<Integer> sortedMonths = new ArrayList<>(monthCaseCountMap.keySet()); Collections.sort(sortedMonths); // 循环累加 for (Integer month : sortedMonths) { Long currentCount = monthCaseCountMap.get(month); // 处理可能的null值,避免空指针 cumulativeSum += currentCount != null ? currentCount : 0; cumulativeMap.put(month, cumulativeSum); } // 打印结果 cumulativeMap.forEach((month, count) -> System.out.printf("%d, %d%n", month, count)); } }
代码说明:
- 先提取所有月份键并排序,保证处理顺序正确;
- 用普通长整型变量累加,逻辑清晰,容易跟踪每一步的累计值;
- 同样用
LinkedHashMap保存结果,维持时间顺序。
注意事项
- 如果你的原始Map已经是有序的(比如用
TreeMap存储,或者LinkedHashMap按时间顺序插入),可以跳过排序步骤,但为了代码的通用性,建议保留排序逻辑; - 如果原始Map的value可能为
null,一定要加上空值判断,避免NullPointerException。
内容的提问来源于stack exchange,提问作者sandeep
相关产品推荐
相关产品推荐

