Java 在ArrayList中使用HashMaps时遇到问题

Java 在ArrayList中使用HashMaps时遇到问题,java,arraylist,hashmap,Java,Arraylist,Hashmap,我在java类中用ArrayLists实现HashMaps时遇到问题。问题是,它一直在向ArrayList添加对象,这就是HashMap,即使我没有更新我的HashMap 这是我无法理解的代码: HashMap<String, ArrayList<String>> map = new HashMap<>(); ArrayList<String> array = new ArrayList<String>(); array.add("O

我在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]!
HashMap map=newhashmap();
ArrayList数组=新的ArrayList();
数组。添加(“一”);
数组。添加(“两个”);
map.put(“键”,数组);
数组。添加(“三”)//2.为什么要将其添加到HashMap中?
System.out.println(map1.get(“Key”);
//1. 这张打印出来的[一,二,三]。。应该是[一,二]!
这意味着您正在将
列表
的引用添加到
映射
。因此,对这一提法的修改随处可见

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

这意味着您正在将
列表
的引用添加到
映射
。因此,对这一提法的修改随处可见


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

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

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

通过引用将ArrayList传递给
map.put()
调用。这意味着在调用后,您的
数组
变量引用相同的对象,因此不进行复制。如果在添加条目时进行复制,那么它将起作用:
map.put(“Key”,newarraylist(array))

通过引用将ArrayList传递给
map.put()
调用。这意味着在调用后,您的
数组
变量引用相同的对象,因此不进行复制。如果在添加条目时进行复制,那么它将起作用:
map.put(“Key”,newarraylist(array))

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

请记住,Java将引用传递给周围的对象(而不是副本),如果容器中引用了一个可变对象,那么该对象仍然可以更改

如果你想避免这种行为,你需要做一个决定。请注意,这通常适用于可变对象(不仅仅是集合),当您传递引用并保持它们时,您需要清楚,任何其他持有该引用的人都可以在不受您控制的情况下更改/变异您的对象。通常最好是创建和传递对象,因为您将对列表的引用添加到地图中,并且您仍然保留原始引用,当您修改该列表时,您正在修改地图中引用的列表

请记住,Java将引用传递给周围的对象(而不是副本),如果容器中引用了一个可变对象,那么该对象仍然可以更改


如果你想避免这种行为,你需要做一个决定。请注意,这通常适用于可变对象(不仅仅是集合),当您传递引用并保持它们时,您需要清楚,任何其他持有该引用的人都可以在不受您控制的情况下更改/变异您的对象。通常最好是创建并传递对象,而不是将
数组列表的引用作为
映射的值添加到

因此,如果只需要前两个值,只需将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"));
HashMap map=newhashmap();
ArrayList数组=新的ArrayList();
数组。添加(“一”);
数组。添加(“两个”);
map.put(“键”,数组);
数组=空//请注意,这并不是真正必要的,只是一个预防措施,您不会使用此引用更改贴图中arraylist的值
array=newarraylist(map.get(“key”));
数组。添加(“三”);
System.out.println(map1.get(“Key”);
输出

[一,二]


您正在将
数组列表的引用添加为
映射的值

因此,如果只需要前两个值,只需将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"));
HashMap map=newhashmap();
ArrayList数组=新的ArrayList();
数组。添加(“一”);
数组。添加(“两个”);
map.put(“键”,数组);
数组=空//请注意,这并不是真正必要的,只是一个预防措施,您不会使用此引用更改贴图中arraylist的值
array=newarraylist(map.get(“key”));
数组。添加(“三”);
System.out.println(map1.get(“Key”);
输出

[一,二]


这就是java中引用的工作方式。您在映射中放置的是对列表的引用,因此在打印映射时,列表中的任何更改都会显示出来。
add()
不会复制列表,它只是插入一个引用。Java就是这样工作的。getKey(“Key”)和数组变量分别引用内存中的同一位置。无论您是通过“数组”引用还是通过map.getKey(“key”)返回的引用添加元素,您都是在内存中的同一位置添加元素。这就是java中引用的工作方式。您在映射中添加的是对列表的引用,因此当您打印映射时,列表中的任何更改都会显示出来。
add()
不复制列表,只插入引用。这就是Java的工作方式。map.getKey(“Key”)和数组变量分别引用内存中的同一位置。无论是通过“array”引用还是通过map.getKey(“Key”)返回的引用添加元素,您正在将元素添加到内存中的同一位置。为什么要先将
array
设置为
null