使用带有ArrayList的HashMaps时遇到麻烦

时间:2015-10-28 14:01:29

标签: java arraylist hashmap

我在java类中使用HashMaps实现ArrayLists时遇到问题。问题是,即使我没有更新我的ArrayList,它仍然会HashMapHashMap添加对象。

这是我无法理解的代码:

HashMap<String, ArrayList<String>> map = new HashMap<>();

ArrayList<String> array = new ArrayList<String>();
array.add("One");
array.add("Two");

map.put("Key", array);

array.add("Three"); //2. Why does this get added to the HashMap?

System.out.println(map1.get("Key"));
//1. This print out [One, Two, Three].. When it should be [One, Two]!

5 个答案:

答案 0 :(得分:3)

通过引用map.put()调用传递ArrayList。这意味着没有复制,在调用后,array变量引用同一个对象。如果您在添加条目时进行复制,那么它将起作用:map.put("Key", new ArrayList<String>(array));

答案 1 :(得分:1)

map.put("Key", array);

这意味着您要向list添加map的引用。因此,随处可见对该参考文献的更改。

如果您不想这样做,请创建一个新列表并添加到其中。

答案 2 :(得分:1)

这是预期的行为。您将列表放入地图,而不是副本,列表本身。因此,如果您稍后修改列表,则地图内的列表(实际列表)也将被修改。

答案 3 :(得分:1)

因为您将引用添加到地图中的列表中,并且仍然保留原始引用,所以当您修改该列表时,您正在修改地图中引用的列表。

请记住,Java将引用传递给对象(而不是副本),如果在容器中引用了可变对象,则仍可以更改该对象。

如果您想避免此行为,则需要制作defensive copy。请注意,这通常适用于可变对象(不仅仅是集合),当你传递引用并保持它们时你需要清楚,持有该引用的任何其他人都可以在没有你控制的情况下改变/改变你的对象。通常最好创建并传递immutable个对象

答案 4 :(得分:0)

您要将ArrayList的引用添加为map的值。

所以如果你只想要前两个值,你可以简单地将你的ArrayList指向null,以确保你不会向它添加东西然后重新启动它

HashMap<String, ArrayList<String>> map = new HashMap<>();

ArrayList<String> array = new ArrayList<String>();
array.add("One");
array.add("Two");

map.put("Key", array);

array=null; //note this isn't really necessary, just a precaution that you won't change the value of arraylist inside the map using this refrence
array=new ArrayList<String>(map.get("key"));
array.add("Three"); 

System.out.println(map1.get("Key"));

<强>输出

  

[one,two]