将 HashMaps 与 ArrayList 一起使用时遇到问题



我在java类中使用ArrayLists实现HashMaps时遇到问题。问题是它不断向ArrayList添加对象是HashMap即使我没有更新我的HashMap

这是我无法理解如何工作的代码:

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]!

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

map.put("Key", array);

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

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

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

由于您将对列表的引用添加到地图中,并且仍保留原始引用,因此当您修改该列表时,您正在修改地图中引用的列表。

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

如果你想避免这种行为,你需要制作一个防御性副本。 请注意,这通常适用于可变对象(不仅仅是集合(,当您传递引用并保存它们时,您需要清楚,持有该引用的其他人可以在没有您控制的情况下更改/更改您的对象。通常最好创建和传递不可变的对象

您正在添加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"));

输出

[一、二]

最新更新