掃二維碼與項目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
散列計算就是計算元素應(yīng)該放在數(shù)組的哪個元素里。準(zhǔn)確的說是放到哪個鏈表里面。按照J(rèn)ava的規(guī)則,如果你要想將一個對象放入HashMap中,你的對象的類必須提供hashcode方法,返回一個整數(shù)值。比如String類就有如下方法:

10年積累的網(wǎng)站設(shè)計、做網(wǎng)站經(jīng)驗,可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識你,你也不認(rèn)識我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有石棉免費網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
- public int hashCode() {
- int h = hash;
- int len = count;
- if (h == 0 && len > 0) {
- int off = offset;
- char val[] = value;
- for (int i = 0; i < len; i++) {
- h = 31*h + val[off++];
- }
- hash = h;
- }
- return h;
- }
注意上面的for循環(huán),有點搞吧?我來舉個例子,讓你很容易明白它在搞什么名堂。比如有一個字符串“abcde”,采用31進(jìn)制的計算方法來計算這個字符串的總和,你會寫出下面的計算式子:
a*31^4+b*31^3+c*31^2+d*31^1+e*31^0.注意,這里的a,b,c,d或者e指的是它們的ASCII值。很有趣的循環(huán),居然可以用來算N進(jìn)制。這個循環(huán)可以抽出來單獨作為計算進(jìn)制的好工具:
- public static void main(String[] args) {
- int[] a={1,0};
- System.out.println(calculate(2,a));
- }
- private static int calculate(int radix,int[] a){
- int sum = 0;
- for(int i=0;i
- sum = sum*radix+a[i];
- }
- return sum;
- }
靜態(tài)方法caculate接受radix作為進(jìn)制基數(shù),數(shù)組a模擬要計算的進(jìn)制的數(shù)字,只是注意表面順序需要一致。比如 01 二進(jìn)制串,在數(shù)組中要按照{(diào)0,1}排列。上面的輸出結(jié)果是1,符合01的真實值。
那么為什么選用31作為基數(shù)呢?先要明白為什么需要HashCode.每個對象根據(jù)值計算HashCode,這個code大小雖然不奢求必須唯一(因為這樣通常計算會非常慢),但是要盡可能的不要重復(fù),因此基數(shù)要盡量的大。另外,31*N可以被編譯器優(yōu)化為
左移5位后減1,有較高的性能。其實選用31還是有爭議,反對者(參考http://stackoverflow.com/questions/299304/why-does-javas-hashcode-in-string-use-31-as-a-multiplier)
認(rèn)為這個東西還是會導(dǎo)致較多的重復(fù),應(yīng)該用更大的數(shù)字。所以,或許將來Java的實現(xiàn)中會有所變化。下面這篇文章介紹了兩個結(jié)論:
1.基數(shù)要用質(zhì)數(shù)
質(zhì)數(shù)的特性(只有1和自己是因子)能夠使得它和其他數(shù)相乘后得到的結(jié)果比其他方式更容易產(chǎn)成唯一性,也就是hash code值的沖突概率最小。
2.選擇31是觀測分布結(jié)果后的一個選擇,不清楚原因,但的確有利。
http://computinglife.wordpress.com/2008/11/20/why-do-hash-functions-use-prime-numbers/
另外,String.hashCode內(nèi)部會緩存第一次計算的值,因為這是一個final(不可變)類,也就是String對象的內(nèi)容是不會變的。這能夠在多次put到HashMap的場合提高性能,不過似乎用處不多。
好了,終于扯完了String.hashCode的話題?,F(xiàn)在繼續(xù)回到HashMap的數(shù)組元素位置計算上來。

我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流