Java library裡本身就對基本的資料類型進implement了不同的hashCode()。要注意的一點是,java 中的 hashCode() 是 int 類型,在64-bit的系統裡,int 就只有32位,所以一些用64-bit的大資料類型(如Long)就要經過一些壓縮處理,才能轉成 int 類型hashCode。這點很重要,也是為什麼Integer 和 Long 類的hashCode() implementation不同的原因。我閱讀了library的原始碼後,按照不同的資料類型,總結一下,1. 對簡單的primitive data types, 像double, int, char等類型, 由於它們不是Object, 所以它們沒有hashCode()的方法,這樣寫code是會有compile error的:
int a = 2;System.out.print( "int a = 2.hashCode()= " );System.out.println(a.hashCode());
2. 對於各自primitive data types的wrapper class,例如Integer, Double, Character等等,它們各自的hashCode() implementation也不一樣,我寫了如下的總結:
Java Wrapper Class hashCode() implementation Summary
| |
| Wrapper Class |
hashCode() implementation |
Note |
| Boolean |
return 1231 or 1237; |
1231 和 1237 是兩個相對較大的質數,請看這裡: http://stackoverflow.com/questions/3912303/boolean-hashcode |
| Byte |
return the byte value ranging from -128 to 127 |
由於Byte類型的所有資訊都存在了低32位中,所以直接返回wrapped的value (converted 成了int 以後的值) |
| Character |
return the character ASCII code |
由於Character類型的所有資訊都存在了低32位中,所以直接返回wrapped的value (converted 成了int 以後的值) |
| Short |
return the short value |
由於Short類型的所有資訊都存在了低32位中,所以直接返回wrapped的value (converted 成了int 以後的值) |
| Integer |
return the int value |
直接返回wrapped的value (converted 成了int 以後的值) |
| Long |
return (int)(value ^ (value >>> 32)); |
由於最後的hashCode的類型是int, 而int只有32位,所以64位的Long值,要砍掉一半。為了不失去一半的資訊,這個expression的意思是,會值的高32位和低32位的值進行exclusive OR的結果,這樣就保證結果均會受前後32位的影響,不會丟失資訊。如果直接把Long轉成int, 那就會丟掉高32位的資訊,這就不是好的implementation |
| Float |
return floatToIntBits(value); |
把float 轉成bits, 具體的implementation是我不是太懂,大概是把32位的float 直接當成int輸出來,不管那些位置資訊,例如本來第31位是符號位,第23到30位代表的是指數,但轉成int值後,這些值代表的意義都不存在了,僅僅作為普通的int數位。 |
| Double |
bits = doubleToLongBits(value); return (int)(bits ^ (bits >>> 32)); |
第一段code與 floatToIntBits(value) 一樣 第二段code是與Long.hashCode()一樣 |
| String |
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] |
s[i] is the ith character of the string; why use 31? http://stackoverflow.com/questions/299304/why-does-javas-hashcode-in-string-use-31-as-a-multiplier 這個公式保證String裡的第一個character都對最後產生的 hashcode 有所影響 |
| |
3. 自訂的class, 如果override了equals()方法,那麼就一定要override hashCode()方法,具體方法請看
http://stackoverflow.com/questions/113511/hash-code-implementation
Some FAQs:Q1. 為何hashCode會是int而不是long呢?答:因為在java中,一個Array的最大長度是:Integer.MAX_VALUE
(http://stackoverflow.com/questions/4166195/why-objecthashcode-returns-int-instead-of-long)Q2. fundamental question(白癡問題): 為什麼Object class會有這個hashCode() ?Object 的 hashCode() 常用在什麼地方?答: hashCode()的本意是一個用來唯一標識object的一個code,可以把它當作加密後的密文。常用在Java內建的HashMap或HashTable的data structure 中。Q3. Object.hashCode() 是如何?的?Here is the link that explains how the Object.hashCode() is implemented: http://stackoverflow.com/questions/2427631/how-is-hashcode-calculated-in-javaAnd also this: http://mindprod.com/jgloss/hashcode.html#OBJECT