天天看點

Why hashcode 31?

前幾天被人問到了hashcode如何實作,說實話,真的是沒有自己寫過,通常情況下都會通過IDE自動生成,慚愧。今天研究了下hashcode的生成原理,首先看一下String類中的hashCode方法:

       核心的算法就是中間的for循環,假如字元串是"abcde",那最終的hash值應該是31(31(31(31a+b) + c) + d) + e,擴号展開為a*31^4+b*31^3+c*31^2+d*31^1+e*31^0,設字元串的長度為n,那最終的計算公式為:s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1],這實際上就是31進制數轉成10進制數的算法。那為什麼要用31作為基數呢?

       我想可能有幾點原因:31首先是一個素數,與素數相乘運算後,能降低hashcode碰撞的機率;31其次是一個特殊的值(32-1),32的二進制是100000,31的二進制是011111,31*N = N << 5 - N,運算速度會快。

       普通類覆寫hashCode方法也可以使用類似的算法,如:

       屬性如果是引用類型,要與其hashCode運算,屬性如果是byte、short、int類型,要與其值運算,屬性如果是float、double、long,要經過特殊運算,可以參考對應封裝類的hashCode方法實作。