为何在该示例中使用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
相关产品推荐
相关产品推荐

