Java基礎之hashCode

1.以String類的hashCode方法爲例:

//jdk1.7源碼

public int hashCode() { int h = hash; if (h == 0 && value.length > 0) { char val[] = value; for (int i = 0; i < value.length; i++) { h = 31 * h + val[i]; } hash = h; } return h; }

以字符“a”爲例,字符‘a’的ascii碼爲97,計算後的h = hashCode爲31*0+97,hash=h=97;

以字符串“abc”爲例,"h = 0" ==> "h = 31*0+97 = 97" ==> "h = 31*97+98 = 3105" ==> "h = 31*3105 + 99 = 96354",即字符串“abc”的hashCode值爲96354。

2.計算原理:

String的hasCode函數以31爲倍數,是因爲31的二進制全是1,可以有效的離散數據,同時前面的字段權重大,這樣的好處是前綴相同的字符串的hash值都落在臨近的區間,hash數組比較小,佔用內存較小,存取效率也高。

3.hash衝突:

以HashMap爲例,在存取鍵值對時,會對key鍵進行hash算法,如果key爲字符串,則調用String的hashCode方法,在數據量大的時候會出現計算後的hashCode相同的情況,即爲hash衝突。

解決方案:HashMap的解決方案是通過鏈表策略解決,即hashCode相同的鍵值對存放到hash數組的同一個下標的 Entry鏈表中;如果存儲位置下標對應的值爲null,則創建Entry並將鍵值對放入其中,再將Entry放入當前下標對應的空間,如果同一下標已經存在Entry,則存放到該Entry鏈表的下一個節點上,以此類推。

除此之外hash衝突的解決方案還有:開放地址法(衝突後尋找數組中下一個空位置),多重散列法(衝突後使用不同的hash函數,再次散列,直到不衝突),公共溢出區法(衝突後將衝突的的鍵值對插入到公共溢出表)。


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