HashMap复制行为我无法弄清楚

时间:2011-10-20 16:12:02

标签: java copy hashmap clone

我无法获取HashMaps的单独副本。我的意思是,一旦我制作了原件的副本,对其中一个进行更改并不会改变另一个。

我有两种HashMaps格式:

HashMap<String, List<String> one = new HashMap<String, List<String>();
HashMap<String, List<String> two = new HashMap<String, List<String>();

我调用下面的函数(getTabSetDifferences)传入一个和两个,正如预期的那样,如果存在一些差异,那些值将从HashMap中删除 它会在传入测试之前与之不同。

我希望它们保持不变,所以尝试了传递:

getTabSetDifferences((HashMap)one.clone(), (HashMap)two.clone())

这仍然改变了原文,所以我创建了两个相同格式的哈希图,并克隆了一个和两个,我使用了新的哈希图来传递 in,原来还是改变了。

然后我尝试了:

HashMap<String, List<String>> holdOne = new HashMap<String, List<String>>();
holdOne.putAll(one);

HashMap<String, List<String>> Holdtwo = new HashMap<String, List<String>>();
holdTwo.putAll(two);

现在我可以这样做:

holdTwo.remove(key);

并且原始版本没有改变,但是如果我用holdOne和holdTwo调用方法它仍然会改变原来的一个和两个哈希图,它们不应该保留吗? 该方法正在工作,并找到我想要的差异,并返回。但是我仍然需要原来的两个哈希图,就像它们一样,但无论哪个 我打电话的方式,对holdOne和holdTwo进行的更改会更改原件。这是预期的行为吗?如果是这样,那么正确的方法是什么 获取与其无关的hashmap的副本。

getTabSetDifferences(holdOne, holdTwo);

public HashMap<String, List<String>> getTabSetDifferences(HashMap<String, List<String>> hmMain, HashMap<String, List<String>> hmSecond)   {
    HashMap<String, List<String>> hmDifferences = new HashMap<String, List<String>>();
    for (Map.Entry<String, List<String>> entry : hmMain.entrySet()) {
        if(hmSecond.containsKey(entry.getKey())) {
            entry.getValue().removeAll(hmSecond.get(entry.getKey()));
            if (entry.getValue().size() > 0)
                hmDifferences.put(entry.getKey(), entry.getValue());
        }
        else {
            hmDifferences.put(entry.getKey(), entry.getValue());
        }
    }
    return hmDifferences;
}

3 个答案:

答案 0 :(得分:2)

我怀疑你只是在复制键/值。这不会创建列表的副本。

也许Guava的MultiMap就是你想要的?

答案 1 :(得分:2)

克隆方法不执行深层复制。

您有2个选项。

  
      
  1. 创建深层复制方法。
  2.   
  3. 使用java.util.concurrent包中的一个Map实现,如copyOnWrite
  4.   

答案 2 :(得分:2)

如果将列表复制为列表(即将其复制到列表范围,而不是某些较低级别的实现),则会看到指针行为....但是如果从一个列表复制到新列表中,那些字符串对象是独立的。

Java的克隆方法不应该用于期望它将返回对象的不同深度副本 - 不可变性不是克隆工作方式的核心概念。

我同意上述评论:要么在像guava这样的库中使用多图,要么谷歌收藏,或者只是非常小心你的复制,只复制原始级别,(不要复制集合和期望它是独立的)除非你明确地测试了它。