插入时映射和列表值歧义:java

时间:2016-07-28 19:44:15

标签: java list hashmap

我正在处理地图中的列表插入,但无法理解插入行为。

public class TestList {

public static void main(String[] args) {

    String strarray[] = new String[5];

    for(int i = 0; i < 5; i++ ){

        strarray[i] = "Demo" + i;
    }

    Map<Integer, List<String>> cluesByText = new HashMap<Integer, List<String>>();
    int j = 0;
    for (String str : strarray) {

        System.out.println(str);
        List<String> s = cluesByText.get(str);
        if (s == null) {
            s = new LinkedList<String>();
            cluesByText.put(j, s);
        }

        s.add(str);
        s.add(str);
        s.add(str);
        s.remove(1);
        // why it is storing without doing cluesByText.put(j,s);
        j++;
    }

    //output is:

    System.out.println(cluesByText);

}
}

问题在于将列表插入到地图中然后通过插入/删除操作更改列表的内容时,它会反映在列表中 存储在上一行的地图中。

打印地图内容的最终输出是。

{0=[Demo0, Demo0], 1=[Demo1, Demo1], 2=[Demo2, Demo2], 3=[Demo3, Demo3], 4=[Demo4, Demo4]}

我无法理解为什么它会以这种方式发生,因为列表的状态已经存储在地图中了?

3 个答案:

答案 0 :(得分:1)

这是预期的行为 - 您在地图中存储对列表的引用,而不是副本。 s中引用了相同的列表,因此如果您通过s添加到列表中,它确实会从地图中看到 - 它只是对同一对象的两个引用。

答案 1 :(得分:1)

请记住(几乎)Java中的所有内容都是参考,而不是值。那么,你所拥有的是从整数到列表的“地址”的映射,而不是列表的“状态”。

当您去学习列表中存储的信息时,计算机会转到该地址以查看其中的内容。

s指定为该列表时,它会将该地址存储在s中。

当您通过s.add()s.remove()对该列表进行更改时,会转到该地址 - 与地图中的地址相同 - 并在那里进行更改。

所以,当你最终通过地图回到那个地址时,你会看到相同的值。

唯一没有发生这种情况的情况是,您将s分配给=运算符:然后您实际上用另一个运算符覆盖了地址,因此查看原始地址的内容是不受影响。

答案 2 :(得分:0)

您有List<String>的引用,因此您可以添加到列表中。如果地图没有条目,则会生成新的List<String>,并将该条目添加到地图中。无论如何,List<String>的范围使其可用于工作。