我想将propertyMap的副本添加到我的propertyMap:
public void addProperties(Map<String, Object> propertyMap) {
for (Map.Entry<String, Object> propertyEntry : propertyMap.entrySet()) {
this.propertyMap.put(propertyEntry.getKey(), propertyEntry.getValue());
}
}
上面的代码没有这样做,但希望传达意图?
最好的方法是什么?我做过一些关于“克隆”,“防御性复制”,“不可变对象”,Collections.unmodifiable ......之类的阅读,但我比以前更加困惑。
我需要的是,在典型的SO风格中,请更好地在代码片段中写出我的意思。
答案 0 :(得分:3)
看起来你可以使用putAll
:
public void addProperties(Map<String, Object> propertyMap) {
this.propertyMap.putAll(propertyMap);
}
这称为“防御性复制”。这里发生的是本地propertyMap
中的值被复制到实例的propertyMap
中。这里的一个弱点是,给定propertyMap
的更改不会反映在实例的propertyMap
中。这实质上是创建给定地图的快照并将该快照复制到实例字段地图。
还有其他方法可以创建防御性副本,包括clone()
和HashMap(Map)
构造函数。
对于不可变集合,Collections
中的不可修改方法将返回在您尝试添加异常时抛出异常的集合。例如,
Set<String> strs = Collections.unmodifiableSet(new HashSet<String>());
strs.add("Error"); // This line throws an exception
不可变集合通过禁止修改(删除和添加)来保护其值,而防御副本通过不引用复制的集合来保护其值(换句话说,原始集合中的更改未显示在副本中)。
答案 1 :(得分:1)
我认为对于每个键,您不必担心复制,因为它们是不可变的。但对于值,它取决于它们是什么类型的对象。如果它们是可变对象,那么你必须复制所有这些对象。
public void addProperties(Map<String, Object> propertyMap) {
Cloner cloner = new Cloner();
for (Map.Entry<String, Object> propertyEntry : propertyMap.entrySet()) {
this.propertyMap.put(propertyEntry.getKey(), cloner.deepClone(propertyEntry.getValue()));
}
}
您可以检查此内容以进行深层克隆Deep clone utility recomendation。
从主页http://code.google.com/p/cloning/
重要提示:深度克隆Java类可能意味着克隆了数千个对象!克隆文件和流可能会导致JVM崩溃。为了查看克隆的内容,强烈建议在开发期间将克隆类转储到stdout。
所以,知道你要克隆的东西很好。