HashSet中hashCode的作用

基礎不牢固,一直不太明白hashCode是幹啥的,慚愧慚愧。
  剛在CSDN論壇上看到了一段解釋,令我豁然開朗。

  在存放集合這種數據的時候,我們可以選擇List和Set兩種形式,當然,Java當中它們不是具體的實現類.我們可以使用具體的實現類進行數據的存儲.
但是List和Set的最顯著區別,應該是,List可以放置相同的元素,Set只能放置不同的元素.也就是說Set裏面的元素具有唯一性.

當然ArrayList和LinkedList也只是具體的實現形式不同了.我們也可以實現一個ArraySet或LinkedSet.但是.我們會發現一個比較嚴重的問題.就是.當我們向ArraySet(或LinkedSet)裏面添加元素的時候,我們要逐個比較裏面的所有已有元素.這樣,當集合中數量非常多的時候,比較次數也會直線上升.也就是說,當我們結合中有10000個元素的時候,我再添加一個元素,要首先比較最多10000次才能確定我要添加的元素是否已經存在了,這會嚴重影響集合的性能.

爲了更快捷的檢索數據,我們才引進了hashCode的概念,每個Set裏面的元素都會有一個hashCode的值,我們可以按照hashCode的值來存儲集合裏面的元素.如果要檢索集合裏面是否存在要添加的元素,只要先將該元素的hashCode值算出來,再到相應的位置進行查找,就可以了.對於相同hashCode的不同元素,我們把這個位置,按照鏈表的形式進行存放.這樣,就可以很大程度上減少比較的次數.舉個例子:

我們Set集合裏面可能已經10000個不同的元素了.當添加新元素的時候,我們根據新元素的hashCode值,找到相應的位置,這個位置所對應的鏈表裏面,可能只有五個元素,那麼,我們只要比較5次,就可以判斷整個集合中是否已經存在該元素了,因爲,相同元素的hashCode一定是相同的.呵呵.爲了使根據hashCode確定位置的速度更快,我們採用數組的下標來表示位置,數組裏面存放鏈表.下標都是自然數,所以,要把hashCode進行向數組下標的映射轉換(其實就是與運算).

最後,來談談,什麼情況下重寫hashCode,我們知道,自然情況下,hashCode所產生的值是很有規律的,這樣的話,擁有10000個元素的Set,可能有9000個都在同一個位置上,這樣,再加一個相同hashCode的元素時,那可能要比較90000次了.所以,我們要自己定義hashCode使得這些元素的hashCode在hashSet裏面存儲更加分散.不過Java的HashSet裏面,已經有一個方法,將元素的hashCode做打散處理了,這個方法對於默認的hashCode還是比較有效果的.對於熟悉這些內容的程序員,爲了程序的效率更高,可以重寫hashCode方法.但是,不能使用隨機數充當hashCode,每個元素,都應該對應唯一的一個hashCode,一個hashCode可以對應多個元素.

也可以這麼說,只要對象內容一樣,我們就有必要重寫它的hashCode,hashCode代表的是對象的內存地址,或者說內存地址根據這個hash碼得到, 一般的集合都重寫了hashCode方法,而當我們自定義對象的時候就要重寫hasdCode方法,保證內容一樣的對象算出相同的hash碼。hash碼的用處只體現在需要散列的地方,如hashSet、hashMap,提高用戶查找速度

發佈了32 篇原創文章 · 獲贊 16 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章