Java拆分大Map为子Map时列表为空的原因排查
问题:拆分Map后列表为空的原因及解决办法
我有一个包含10000个键的Map<String, List<Integer>>,希望将其拆分为包含50个各含200个元素的子Map的列表。以下是我的实现代码:
Map<String, List<Integer>> map = new HashMap<>(); for (int i = 0; i < 10000; i++) { map.put(String.valueOf(i),new ArrayList<>(Arrays.asList(new Random().nextInt(100),new Random().nextInt(200),new Random().nextInt(300) ,new Random().nextInt(400)))); } List<Map<String, List<Integer>>> list = new ArrayList<>(); Map<String,List<Integer>> submap = new TreeMap<>(); List<Map<String, List<Integer>>> sublist = new ArrayList<>(); for (Map.Entry<String, List<Integer>> stringListEntry : map.entrySet()) { submap.put(stringListEntry.getKey(),stringListEntry.getValue()); if (submap.size() == 200){ sublist.add(submap); list.addAll(sublist); sublist.clear(); submap.clear(); } } System.out.println(list);
但最终输出的列表为空,请问这是为什么?
原因分析
- 引用传递导致的清空问题:你把
submap添加进sublist,再将sublist内容合并到list后,立刻调用了submap.clear()和sublist.clear()。由于Java中集合是引用传递,list里存储的是对submap的引用而非副本,清空原对象后,list里的所有元素都会变成空Map。 - 多余的中间列表
sublist:这个列表完全没必要存在,多一层操作不仅增加代码复杂度,还容易引发引用相关的错误。 - 边界情况未处理:如果原Map元素总数不是200的整数倍,最后一批不足200的元素会被直接丢弃,你的代码没有处理这种场景。
修正后的代码
Map<String, List<Integer>> map = new HashMap<>(); Random random = new Random(); // 统一创建Random实例,避免重复初始化 for (int i = 0; i < 10000; i++) { map.put(String.valueOf(i), new ArrayList<>(Arrays.asList( random.nextInt(100), random.nextInt(200), random.nextInt(300), random.nextInt(400) ))); } List<Map<String, List<Integer>>> list = new ArrayList<>(); Map<String, List<Integer>> submap = new TreeMap<>(); for (Map.Entry<String, List<Integer>> entry : map.entrySet()) { submap.put(entry.getKey(), entry.getValue()); if (submap.size() == 200) { // 创建新的Map副本添加进list,避免后续清空影响已存入的内容 list.add(new TreeMap<>(submap)); submap.clear(); } } // 处理最后一批不足200个的剩余元素 if (!submap.isEmpty()) { list.add(submap); } System.out.println(list.size()); // 输出50,符合预期
修正说明
- 移除了多余的
sublist,直接操作目标列表list,简化逻辑 - 添加子Map时,通过
new TreeMap<>(submap)创建副本,确保list中存储的是独立的Map实例,后续清空submap不会影响已存入的内容 - 增加了剩余元素的处理逻辑,保证所有元素都被拆分到子Map中
- 优化了
Random实例的创建,避免循环内重复初始化,提升性能
内容的提问来源于stack exchange,提问作者M. Todoroff
相关产品推荐
相关产品推荐

