简体   繁体   English

我不知道HashMap复制行为

[英]HashMap Copy behavior I can't figure out

I am having trouble getting a separate copy of my HashMaps. 我在获取HashMap的单独副本时遇到了麻烦。 By that I mean, once I have made a copy of the original, making a change to one does not change the other. 我的意思是,一旦我复制了原件,对其中一个进行更改就不会更改另一个。

I have two HashMaps in this format: 我有两个这种格式的HashMap:

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

I call the following function below (getTabSetDifferences) passing in one and two, as expected if there are some differences, those values will be removed from the HashMap and it'll be different than before it was passed in for the test. 我调用下面的函数(getTabSetDifferences),传入一个和两个,如预期的那样,如果存在一些差异,这些值将从HashMap中删除,并且将不同于传递给测试之前的值。

I want them to remain unchanged, so tried passsing in: 我希望它们保持不变,因此尝试传递:

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

This still changed the originals, so i created two more hashmaps in the same format, and cloned one and two to them, I used the new hashmaps to pass in, and the original was still changed. 这仍然改变了原图,因此我又以相同的格式创建了两个哈希图,并向它们克隆了一个和两个,然后使用新的哈希图进行传递,原始图仍然被更改。

I then tried: 然后,我尝试:

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);

Now I can do something like: 现在我可以做类似的事情:

holdTwo.remove(key);

and the original is not changed, but if i call the method with holdOne and holdTwo it still changes the original one and two hashmaps, shouldn't they remain? 并且原来的没有改变,但是如果我用holdOne和holdTwo调用方法,它仍然会改变原来的一个和两个哈希图,它们不应该保留吗? The method is working, and finding the differences i want, and is returned. 该方法正在工作,并找到我想要的差异,然后返回。 But I still need the original two hashmaps to be as they were, but no matter which way I call, what ever changes are made to holdOne and holdTwo changes the originals. 但是我仍然需要原始的两个哈希图保持原样,但是无论我用哪种方式调用,对holdOne和holdTwo所做的更改都会改变原始哈希图。 Is that the expected behavior? 这是预期的行为吗? If so, what is the proper way to get a copy of a hashmap that is not tied to it. 如果是这样,什么是获取不受约束的哈希图副本的正确方法。

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;
}

I suspect you are only copying the keys/values. 我怀疑您只是在复制键/值。 This will not create copies of the lists. 这不会创建列表的副本。

Perhaps Guava's MultiMap is what you want? 也许番石榴的MultiMap是您想要的?

The clone method doesn't do a deep copy. clone方法不做深层复制。

You have 2 options. 您有2个选择。

  1. create a deep copy method. 创建深层复制方法。
  2. Use one of the Map implementations from the java.util.concurrent package like copyOnWrite 使用java.util.concurrent包中的Map实现之一,例如copyOnWrite

If you copy the list as a list (ie copy it at list scope, rather than some lower level implementation), then the pointer behavior will be seen.... However if you copy from one list into a new list, then those string objects are independant. 如果将列表复制为列表(即在列表范围而不是较低级别的实现中复制),则将看到指针行为。...但是,如果从一个列表复制到新列表中,则这些字符串对象是独立的。

Java's clone method should not be use in expectation that it will return distinct , deep copies of an object - immutability is not a central concept to the way clone works. 不应该使用Java的clone方法来期望它会返回对象的不同的深层副本-不变性不是克隆工作方式的核心概念。

I agree with the above comment : either use a multimap in a library like guava, or google collections, or simply be very careful about your copying, and only copy at the primitive levels, (don't ever copy a collection and expect it to be independent) unless you've tested this explicitly . 我同意以上评论:要么在guava之类的库中使用多图,要么在google集合中使用多图,或者只是非常小心地进行复制,而仅在原始级别进行复制(永远不要复制一个集合并期望它是独立的),除非您已经对此进行了明确的测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM