You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,符合预期

修正说明

  1. 移除了多余的sublist,直接操作目标列表list,简化逻辑
  2. 添加子Map时,通过new TreeMap<>(submap)创建副本,确保list中存储的是独立的Map实例,后续清空submap不会影响已存入的内容
  3. 增加了剩余元素的处理逻辑,保证所有元素都被拆分到子Map中
  4. 优化了Random实例的创建,避免循环内重复初始化,提升性能

内容的提问来源于stack exchange,提问作者M. Todoroff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 09:55:28