我正在创建一个HashMap,如下所示:
private HashMap <String, JSONArray> HiveMap;
HiveMap = new HashMap <String, JSONArray>();
还有一个私有类变量,用于存储一些计算数据,这些数据将在计算完成后放入HashMap中:
private JSONArray hiveList;
计算hiveList后,我将hiveList放入创建的HashMap(HiveMap)中:
HiveMap.put(hiveNode,hiveList);
当我现在打印出HiveMap时,我得到的输出符合预期,Hashmap中存在hiveNode
和hiveList
字段。 <"hiveNode":"hiveList">
完成此操作后,我假设我从hiveList
放入HashMap的数据将继续存在,因此我使用hiveList.clear();
清除hiveList数组
但是当我清除hiveList后打印Hashmap时,我发现来自hiveList的数据也从HashMap中消失了。
清除hiveList后打印HashMap导致:<"hiveNode": >
我不明白这种行为,如果有人能对此有所了解,我将不胜感激。
答案 0 :(得分:8)
错误是这样的:
完成此操作后,我假设从hiveList放入HashMap的数据将继续存在,因此我使用hiveList.clear()清除hiveList数组;
传递给哈希映射的是对列表的引用,而不是它的副本。
最简单的解决方法是创建一个新实例而不是清除它。或者,您可以制作副本,并将其放在地图中。
答案 1 :(得分:3)
hiveList
列表和Map
中作为值的列表是同一个,变量和Map
都包含引用对同一个对象;如果你clear()
一个清单,另一个也清空 - 有一个清单,而不是两个清单。
如果由于某种原因必须清除并重用hiveList
(我不明白为什么),那么您需要在{{1}中添加不同的列表这里是如何做一个浅拷贝:
Map
将HiveMap.put(hiveNode, new ArrayList<Hive>(hiveList));
替换为列表中元素的实际类型。
答案 2 :(得分:3)
在java对象中,通过引用的副本传递而不是对象的副本。因此,如果您在一个地方使用引用修改对象,则会在引用此对象的所有位置受到影响。在你的情况下hiveList.clear();
导致删除列表中的所有元素,这些元素也在HiveMap.put(hiveNode,hiveList);
引用,因此最终会从地图中删除。
答案 3 :(得分:2)
这就是java管理Object的方式。你拥有的是对该对象的引用,你只存储了对它的引用。因此,如果在将对象存储在hashmap中之后清除该对象,则也会清除hashmap中的对象。
创建对象时,java会将引用与对象一起存储在内存中的相同位置。因此,只有一个对该对象的引用。所以,结果是预期的
//Stores the reference to the object
HiveMap.put(hiveNode,hiveList);
//Modifies the same object in the memory
hiveList.clear();