ArrayList與HashSet的比較,以及HashCode分析, 內存泄露

http://www.360doc.com/content/14/0718/16/8072791_395303870.shtml


看下面這兩個小示例:

 
 
 那爲什麼HashSet中的集合個數是3個呢,我明明在集合中存了4個元素啊?

這是因爲:在ArrayList集合中,保存對象是按照順序保存的,將每一個實例放到一個位置。
而HashSet集合,插入一個元素的插後,他會判斷,這個元素則集合中是否存在,如果存在,就不插入了,注意不是替換,是不插入了。如果想吧這個元素插入,那就必須把原來的元素刪除。

那麼在集合c中,第一個元素和第三個元素想不想等呢?作爲程序員,我希望他想等,那怎麼做呢?
解決上面的提問:第一個,他們肯定是不相等的。HashSet比較是根據HashCode的值來比較的,HashCode值是根據內存地址換算出來的,這是兩個對象,內存地址肯定不一樣,所以用“==”來比較肯定不等,用equals方法來比較,我們沒有重寫,那也不相等。
第二個問題:那我想讓他想等,怎麼辦?重寫equals方法。

我們在ReflectPoint.java中生成hashCode和equals方法。
 
 
這個時候再來看看,集合中有幾個元素?答案是集合中有兩個元素 
 下面來講講這個HashCode的作用。
我們把ReflectPoint中的hashCode()方法刪除掉,看看集合中有幾個元素,答案是可能是3個也可能是2個。
 
 
 
那爲什麼會這樣呢?我們來分析一下,hashCode的作用:
 
 
注意:要想一個對象有hashCode方法有價值的話,必須將這個對象存儲在Hash集合中。加入文件沒有這樣的集合,而是ArrayList,那麼hashCode就沒有用了。

回到剛剛的問題上來,爲什麼我沒有實現hashCode方法,集合中元素個數就等於3了呢?因爲,每一個對象算出來的哈希值,是根據內存來算的。對象rp1根據內存算出來的哈希值存在第1個區域,而對象rp3根據內存算出來的哈希值存在第8個區域,雖然在其他區域有跟我一樣的對象,但我卻只跟集合內部比較。這就是爲什麼集合個數是3了。那如果恰巧rp1和rp3在同一個集合,那就比較出來了他們是相等的,這是集合個數就是2了。
爲了讓相等的對象,放在相同的區域,那麼就有一種說法,如果兩個對象的相等的話(equals相等),那麼讓他們的hashCode也相等。這就是寫hashCode的原因了。

這裏有一個很重要的知識點:
 
  
 


我們來分析一下原因,爲什麼會這樣呢?我改一個值,就取不走了呢?因爲我一改x的值,這個對象的hashCode就變了, 不在原來的區域了。 刪除的時候我在這個區域裏找原來的那個hashCode值,找不到,我就刪除失敗了。這樣就導致內存泄露了,我以爲把他刪除掉了,實際上呢?沒有刪除掉。這樣長時間的新增,修改刪除對象,日積月累,就導致內存溢出了。這就是內存泄露的一個現象。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章