如何用Java Lambda与Stream将嵌套Map的周数据转换为月数据
用Java Stream优化嵌套Map的周度转月度指标聚合
核心思路
外层按国家分组,内层将每个国家的周数据按月份归类,再对数值型指标(customerViews、productSales等)做求和聚合,自动跳过缺失的周或缺失的指标。
实现代码
首先实现周标识转月份的工具方法(假设周格式为yyyy-Www,如2024-W01):
import java.time.LocalDate; import java.time.format.DateTimeFormatter; private static String getMonthFromWeek(String weekStr) { String[] parts = weekStr.split("-W"); int year = Integer.parseInt(parts[0]); int week = Integer.parseInt(parts[1]); // 计算该周对应的月份,格式为yyyy-MM return LocalDate.ofYearDay(year, week * 7) .format(DateTimeFormatter.ofPattern("yyyy-MM")); }
然后用Stream完成聚合逻辑:
import java.util.*; import java.util.stream.Collectors; // 原始输入数据:Map<String, Map<String, Object>> countryWeeklyData Map<String, Map<String, Object>> countryMonthlyData = countryWeeklyData.entrySet().stream() .collect(Collectors.toMap( Map.Entry::getKey, // 保留国家作为外层Map的Key countryEntry -> countryEntry.getValue().entrySet().stream() // 过滤掉非指标Map的脏数据 .filter(weekEntry -> weekEntry.getValue() instanceof Map) // 按月份分组周数据 .collect(Collectors.groupingBy( weekEntry -> getMonthFromWeek(weekEntry.getKey()), // 对同月份的所有周指标求和 Collectors.collectingAndThen( Collectors.toList(), weekEntries -> { Map<String, Object> monthlyMetrics = new HashMap<>(); // 定义需要聚合的数值型指标列表 List<String> targetMetrics = Arrays.asList( "customerViews", "productSales", "noOfUnitsSold", "conversion" ); targetMetrics.forEach(metric -> { double total = weekEntries.stream() .map(weekEntry -> (Map<String, Object>) weekEntry.getValue()) // 跳过缺失当前指标的周数据 .filter(metricMap -> metricMap.containsKey(metric)) .mapToDouble(metricMap -> ((Number) metricMap.get(metric)).doubleValue()) .sum(); monthlyMetrics.put(metric, total); }); return monthlyMetrics; } ) )) ));
关键细节说明
- 周转月逻辑:如果你的周标识格式不是
yyyy-Www,直接修改getMonthFromWeek方法的解析规则即可(比如yyyyMMww格式可以用字符串截取+日期解析)。 - 缺失值处理:通过
filter跳过没有目标指标的周数据,避免空指针;缺失的周数据会自动被忽略,不影响同月份其他周的求和。 - 类型适配:如果指标是整数类型(如customerViews),求和后可以将
double total转为long total再存入Map,贴合数据类型需求。 - 空数据过滤:如果需要排除没有任何周数据的国家,可在外层Stream添加
.filter(entry -> !entry.getValue().isEmpty())。
内容的提问来源于stack exchange,提问作者YouKnowWho
相关产品推荐
相关产品推荐

