我正在处理地图中的列表插入,但无法理解插入行为。
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]}
我无法理解为什么它会以这种方式发生,因为列表的状态已经存储在地图中了?
答案 0 :(得分:1)
这是预期的行为 - 您在地图中存储对列表的引用,而不是副本。 s
中引用了相同的列表,因此如果您通过s
添加到列表中,它确实会从地图中看到 - 它只是对同一对象的两个引用。
答案 1 :(得分:1)
请记住(几乎)Java中的所有内容都是参考,而不是值。那么,你所拥有的是从整数到列表的“地址”的映射,而不是列表的“状态”。
当您去学习列表中存储的信息时,计算机会转到该地址以查看其中的内容。
将s
指定为该列表时,它会将该地址存储在s
中。
当您通过s.add()
或s.remove()
对该列表进行更改时,会转到该地址 - 与地图中的地址相同 - 并在那里进行更改。
所以,当你最终通过地图回到那个地址时,你会看到相同的值。
唯一没有发生这种情况的情况是,您将s
分配给=
运算符:然后您实际上用另一个运算符覆盖了地址,因此查看原始地址的内容是不受影响。
答案 2 :(得分:0)
您有List<String>
的引用,因此您可以添加到列表中。如果地图没有条目,则会生成新的List<String>
,并将该条目添加到地图中。无论如何,List<String>
的范围使其可用于工作。