Java 更新 HashSet<Integer> 类型的 HashMap 值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20038579/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 22:33:04  来源:igfitidea点击:

Update HashMap values of type HashSet<Integer>

javahashmap

提问by TonyGW

I have trouble updating the HashMap values of Set type. After initializing the HashMap with key-values pair, I want to insert a new value to the the existing value Set, and the new value is to be incremented for each insert. My code is following:

我无法更新 Set 类型的 HashMap 值。使用键值对初始化 HashMap 后,我想在现有值 Set 中插入一个新值,并且每次插入都会增加新值。我的代码如下:

    public static void main(String[] args)
    {
        String[] mapKeys = new String[]{"hello", "world", "america"};
        Map<String, Set<Integer>> hashMap1 = new HashMap<String, Set<Integer>>();
        Set<Integer> values = new HashSet<Integer>();

        for (int i = 0; i < 10; i++)  // initialize the values to a set of integers[1 through 9]
        {
            values.add(i);
        }

        for (String key : mapKeys)
        {
            hashMap1.put(key, values);
        }

        StdOut.println("hashMap1 is: " + hashMap1.toString());

        int newValues = 100; // insert this newValues (incremented at each insert) to each value
        Set<Integer> valuesCopy;

        for (String key : mapKeys)
        {
            if (hashMap1.containsKey(key))
            {
                valuesCopy = hashMap1.get(key); // first, copy out the existing values

                valuesCopy.add(newValues++); // insert the newValues to the value Set
                hashMap1.remove(key);// remove the existing entries
                hashMap1.put(key, valuesCopy); // insert the key-value pairs

            }
        }

        StdOut.println("the updated hashMap1 is: " + hashMap1.toString());


    }

When executing the code, each HashMap key is associated with the same set of Integers: [102, 0, 1, 2, 100, 3, 101, 4, 5, 6, 7, 8, 9], however, what I really want is insert only one number to each set, this is what I want: [0, 1, 2, 100, 3, 4, 5, 6, 7, 8, 9]

执行代码时,每个 HashMap 键都与同一组整数相关联:[102, 0, 1, 2, 100, 3, 101, 4, 5, 6, 7, 8, 9],然而,我真正想要的是每组只插入一个数字,这就是我想要的:[0, 1, 2, 100, 3, 4, 5, 6, 7, 8, 9]

I need help understanding this: why all the new inserted values are the same? how to make it work as I wish? thanks for help

我需要帮助理解这一点:为什么所有新插入的值都相同?如何让它按照我的意愿工作?感谢帮助

回答by Engine Bai

First of all, when you execute if (hashMap1.containsKey(key)), the java loops to check each key to check existence of key automatically, so that you don't need to write the for loop code by yourself.

首先,当你执行时if (hashMap1.containsKey(key)),java循环检查每个key自动检查key是否存在,这样你就不需要自己写for循环代码了。

Then, you don't need to write hashMap1.remove(key)because that when insert a exist key to java map, the map will find the existed (key, value) pair and overwrite the new (key, value) pair.

然后,您不需要编写,hashMap1.remove(key)因为当向 java map 插入一个存在键时,映射会找到存在的 (key, value) 对并覆盖新的 (key, value) 对。

Here is the modified code after Set<Integer> valuesCopy;:

以下是修改后的代码Set<Integer> valuesCopy;

if (hashMap1.containsKey(key))
{
    valuesCopy = hashMap1.get(key); // first, copy out the existing values
    valuesCopy.add(newValues++); // insert the newValues to the value Set
    hashMap1.put(key, valuesCopy); // insert the key-value pairs
}

Just remove for (String key : mapKeys)and hashMap1.remove(key)code segment, and then you may get the result that you want.

只需删除for (String key : mapKeys)hashMap1.remove(key)编码段,然后您可能会得到您想要的结果。

回答by Siyuan Ren

The reason is that the every object symbol in Java is a reference to the actual object. In this part

原因是Java中的每个对象符号都是对实际对象的引用。在这部分

for (String key : mapKeys)
{
    hashMap1.put(key, values);
}

you associate each key with the reference to the same Set<Integer>, so when you change one of them, all of them are changed.

您将每个键与对相同的引用相关联Set<Integer>,因此当您更改其中一个时,所有键都会更改。

The correct way to do this is

正确的做法是

for (String key : mapKeys)
{
    hashMap1.put(key, new HashSet<Integer>(values));
}

This way every key will have its own copy of Setinitialized with the content of values.

这样每个键都会有自己的副本,Setvalues.

With this fact, you can also see that the code here

有了这个事实,你也可以看到这里的代码

            valuesCopy = hashMap1.get(key); // first, copy out the existing values

            valuesCopy.add(newValues++); // insert the newValues to the value Set
            hashMap1.remove(key);// remove the existing entries
            hashMap1.put(key, valuesCopy); // insert the key-value pairs

is verbose and introduces unnecessary overhead. Simply use

冗长并引入了不必要的开销。只需使用

hashMap1.get(key).add(newValues++);