在Hashtable上调用Collection values()时,Java是否会复制数据?

时间:2012-06-05 02:27:48

标签: java memory-management hashtable

我想迭代Hashtable的值,它具有大量数据(apx.1 GB)。为此,我正在使用:

Hashtable<String,Object> myHashtable = new Hashtable<String,Object>;

// Fill the Hashtable here...

// Get the values as a Collection:
Collection<Object> myValues = myHashtable.values();

// Get the values as an array:
ArrayList<Object> myArray = myValues.toArray();

// Iterate through the values here...

所以,我的问题是:我是否将存储的数据相乘?我是否有3个相同值的副本存储在RAM中(Hashtable中有一个副本,Collection中有一个copye,ArrayList中有一个副本)?

如果答案是肯定的,我复制了数据,有没有办法迭代Hashtable的值而不重复数据?

如果答案为否,那么这是否意味着Collection存储指针?在这种情况下,如果我在创建集合后修改Hashtable中的数据,那么集合是否反映了这种变化? (与ArrayList相同的问题)。

谢谢!

2 个答案:

答案 0 :(得分:2)

values()方法重复数据,根据documentation,它会返回地图中值的视图 - 这意味着:如果您更改了元素myValues然后更改将反映在原始地图上。

另一方面,toArray() 会重复重复数据(并且会返回数组,而不是代码所暗示的ArrayList )因为它创建了一个新的数组,其中包含myValues中元素的浅层副本。此外,因为数组保存对原始地图中元素的引用,如果对象是可变的,它们上的更改将反映在地图上 - 但是如果您修改数组本身(例如,设置为null,则其中一个元素)会更改不会反映在地图上。

迭代遍历地图值而不创建其他副本的最简单方法是在值上使用迭代器:

for (Object val : myHashtable.values()) {
    // do something with each value
}

请记住,因为地图中的值,myValues的内容和myArray的内容都是对相同对象的引用,您对它们所做的任何更改都会反映在其他对象上同样(假设它们是可变的。)

答案 1 :(得分:2)

看看the Hashtable.values() documentation

  

集合由地图支持,因此对地图的更改会反映在集合中,反之亦然。

返回的Collection包含对Hashtable中存储的相同对象的引用,因此数据不会“重复”;它只是Hashtable视图。如果您更改其中一个存储的对象,您将观察到HashtableCollection中的更改(因为它是同一个对象)。