Java如何向嵌套Map<String,Map<LocalDate,List<Integer>>>的内层Map插入值
问题根因
你的代码核心错误是所有国家复用了同一个内部Map实例:你仅在最外层初始化了一次innerMap,后续给所有国家绑定的都是这同一个Map对象,任意国家的数据修改都会作用到全局唯一的内部Map上,自然会出现所有数据都堆到同一个位置的异常。
修复代码
首先需要为每个国家单独创建独立的内部Map,禁止复用同一个实例,参考实现如下:
import java.time.LocalDate; import java.util.*; import java.util.stream.Collectors; // 原有变量说明: // 1. keys:已解析好的表头日期列表(类型为List<LocalDate>) // 2. mapKeys:所有国家名称列表(类型为List<String>) // 3. covidListWithoutCountryDetails:原始数据源(类型为List<List<String>>) Map<String, Map<LocalDate, List<Integer>>> dataMap = new LinkedHashMap<>(); // 为每个国家初始化独立的内部日期Map for (String country : mapKeys) { Map<LocalDate, List<Integer>> countryDateMap = new LinkedHashMap<>(); for (LocalDate date : keys) { countryDateMap.put(date, new ArrayList<>()); } dataMap.put(country, countryDateMap); } // 填充各国每日数据 // 数据源第一行是表头,从第二行开始是各国数据 for (int i = 1; i < covidListWithoutCountryDetails.size(); i++) { List<String> rowData = covidListWithoutCountryDetails.get(i); String country = rowData.get(1).trim(); // 数据源前4列是省份、国家、纬度、经度,从第5列(索引4)开始是每日病例数 for (int dateIdx = 0; dateIdx < keys.size(); dateIdx++) { int caseNum = Integer.parseInt(rowData.get(4 + dateIdx).trim()); dataMap.get(country).get(keys.get(dateIdx)).add(caseNum); } }
如果需要用Stream风格实现,也可以参考如下写法:
Map<String, Map<LocalDate, List<Integer>>> dataMap = mapKeys.stream() .collect(Collectors.toMap( country -> country, // 每个国家生成独立的内部日期Map country -> keys.stream() .collect(Collectors.toMap( date -> date, date -> new ArrayList<>(), (oldV, newV) -> oldV, LinkedHashMap::new )), (oldV, newV) -> oldV, LinkedHashMap::new ));
效果验证
上述代码执行后,dataMap的结构就和你期望的输出完全一致,每个国家的日期数据独立存储,不会互相干扰。
内容的提问来源于stack exchange,提问作者mike kong
相关产品推荐
相关产品推荐

