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

为何在该示例中使用putAll()实现深拷贝无效?

为什么HashMap的putAll()没有实现预期的深拷贝?

运行以下Java代码后,可明显看到原map的数值随futureMap的变化而改变,明明用了putAll()尝试实现深拷贝,却没有生效,这是什么原因?

import java.util.HashMap;

public class test {
    public static void main(String[] args) {
        HashMap<String, Object> map1 = new HashMap<>();
        HashMap<String, Object> map2 = new HashMap<>();
        HashMap<String, Object> map3 = new HashMap<>();
        map3.put("isEnd", 2);
        map2.put("x", map3);
        map1.put("y", map2);
        String sentence = "xyxy";
        sensitiveWordFilter(sentence, map1);
    }

    public static String sensitiveWordFilter(String sentence, HashMap<String, Object> map){
        System.out.println("original map: " + map);
        HashMap<String, Object> futureMap = new HashMap<>();
        for(int i = 0; i < sentence.length(); i++){
            char char_ = sentence.charAt(i);
            for (String key : map.keySet()){
                if (String.valueOf(char_).equals(key)){
                    HashMap<String, Object> tempMap = new HashMap<>();
                    tempMap.putAll((HashMap<String, Object>) map.get(key));
                    HashMap<String, Object> newMap = new HashMap<>();
                    newMap.put(key, tempMap);
                    futureMap = newMap;
                }
            }

            if (futureMap.get(String.valueOf(char_)) != null){
                futureMap = (HashMap<String, Object>) futureMap.get(String.valueOf(char_));
                if (futureMap.get("isEnd") != null){
                    System.out.println("---------------" + map + "--------------------");
                    futureMap.remove("isEnd");
                    System.out.println("---------------" + map + "--------------------");
                }
            }
        }
        return sentence;
    }
}

原因解析

  • putAll()仅完成浅拷贝:putAll()方法只会复制HashMap顶层的键值对,但对于值是引用类型(比如嵌套的HashMap)的情况,它复制的是对象引用,而不是创建一个全新的对象。
  • 代码中的引用未断开:当你执行tempMap.putAll((HashMap<String, Object>) map.get(key))时,tempMap里存储的是原嵌套HashMap(比如map3)的引用,而非独立副本。后续通过futureMap操作这个引用时,本质上是直接修改原map3对象,所以原map1的内容会同步变化。
  • 深拷贝需要递归处理嵌套结构:如果要实现真正的深拷贝,你需要递归遍历每一层的HashMap,对每个引用类型的value都创建新的副本,而不是直接复制引用。比如编写一个递归方法,判断每个value是否为HashMap,若是则递归拷贝该HashMap后再放入新容器。

内容的提问来源于stack exchange,提问作者speed milo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 08:22:31