-1

我正在创建一个 HashMap 如下:

private HashMap <String, JSONArray> HiveMap;
HiveMap = new HashMap <String, JSONArray>();

还有一个私有类变量,用于存储一些计算数据,这些数据将在计算完成后放入 HashMap:

private JSONArray hiveList;

计算完hiveList后,我把hiveList放到创建的HashMap(HiveMap)中:

HiveMap.put(hiveNode,hiveList);

当我现在打印出 HiveMap 时,我得到的输出与预期的一样,包含字段hiveNode并存hiveList在于 Hashmap 中。<"hiveNode":"hiveList">

完成此操作后,我假设我从中放入 HashMap 的数据hiveList将持续存在,因此我使用清除 hiveList 数组hiveList.clear();

但是当我在清除 hiveList 后打印 Hashmap 时,我看到 hiveList 中的数据也从 HashMap 中消失了。

清除 hiveList 后打印 HashMap 会导致:<"hiveNode": >

我不理解这种行为,如果有人能对此有所了解,我将不胜感激。

4

4 回答 4

8

错误是这样的:

完成此操作后,我假设我从 hiveList 放入 HashMap 的数据将持续存在,因此我使用 hiveList.clear(); 清除 hiveList 数组;

传递给哈希映射的是对列表的引用,而不是它的副本。

最简单的解决方法是创建一个新实例而不是清除它。或者,您可以制作一个副本,并将其放入地图中。

于 2013-08-06T18:30:06.393 回答
3

hiveList列表和作为值驻留在 中的列表是相同Map的,变量和Map都持有对同一对象的引用;如果您clear()列出一个列表,则另一个列表也将被清空-只有一个列表,而不是两个。

如果您出于某种原因必须清除和重用hiveList(我不明白为什么),那么您需要在 中放置一个不同的列表Map,这里是如何进行浅拷贝:

HiveMap.put(hiveNode, new ArrayList<Hive>(hiveList));

替换<Hive>为列表中元素的实际类型。

于 2013-08-06T18:31:17.177 回答
3

在 java 中,对象是通过引用的副本而不是对象的副本传递的。因此,如果您在一个地方使用引用修改对象,它会在引用该对象的所有地方受到影响。在您的情况下hiveList.clear();
,导致删除列表中的所有元素,这些元素也被引用,HiveMap.put(hiveNode,hiveList);因此最终从地图中删除。

于 2013-08-06T18:33:38.727 回答
2

这就是java管理对象的方式。您拥有的是对该对象的引用,而您只存储了对该对象的引用。因此,如果您在将对象存储到 hashmap 后清除它,则 hashmap 中的对象也将被清除。

创建对象时,java 将引用与对象一起存储在内存中的同一位置。因此,只有一个对该对象的引用。所以,结果在意料之中

//Stores the reference to the object
HiveMap.put(hiveNode,hiveList);

//Modifies the same object in the memory
hiveList.clear();

您可能想阅读有关按引用传递和按值传递的信息

于 2013-08-06T18:32:22.467 回答