5

我想将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 风格,是一种更好的方式来写我在代码片段中的意思,拜托。

4

2 回答 2

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

不可变集合通过禁止修改(删除和添加)来保护它们的值,而防御性副本通过不引用复制的集合来保护它们的值(换句话说,原始集合中的更改不会显示在副本中)。

于 2012-09-11T17:11:33.540 回答
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())); 
    } 
} 

您可以检查此深度克隆深度克隆实用程序推荐

从主页http://code.google.com/p/cloning/

重要提示:Java 类的深度克隆可能意味着数千个对象被克隆!文件和流的克隆也可能导致 JVM 崩溃。强烈建议在开发期间启用将克隆的类转储到标准输出,以便查看克隆的内容。

因此,很高兴知道您要克隆的内容。

于 2012-09-11T17:19:46.580 回答