前言

在Java中,每个对象都有一个从Object基类派生出的 hashCode() 方法,用于根据当前对象的某些特征返回一个整型变量。其核心源代码(省略一些类型判断与验证代码)如下所示:

public static int hashCode(byte[] value) {
    int h = 0;
    for (byte v : value) {
        h = 31 * h + (v & 0xff);
    }
    return h;
}

那么为什么要这么计算,31这个数字是哪来的,本文将从理论和实践层面进行详细说明。

计算公式

java hash计算的值多长 java hashcode计算方法_Java

 

 

为什么是数字31?

由于哈希码(HashCode)的目的是为了区分对象,所以其分布自然是越均匀越好。为了保证分布均匀,一般的方法是使用一些相对大的素质,但是为什么选择了31,而不是 23、29、37 或者直接更大的,如97?

在 《Effective Java》48页,第 3 章 “Always override hashcode when you override equals” 写道[2]:

A nice property of 31 is that the multiplication can be replaced by a shift and a subtraction for better performance: 31 * i == (i << 5) - i. Modern VMs do this sort of optimization automatically.

 

也就是说 31 * i 可以用 (i << 5) - i 来计算,而移位操作的效率高于乘法,所以这是基于性能角度的考虑。所以31即满足素数的要求,又可以快速计算,所以被使用在对极致性能要求的Java源代码中。

结论

通过源代码,我们可以看到Java对性能有极致的追求,就hashCode的实现代码中,做了两大优化:
1)使用加乘运行代替连续阶乘运算以提高效率;
2)使用可以用位左移操作计算的31代替其他运算。

转载:

 

 


TRANSLATE with x

English

Arabic

Hebrew

Polish

Bulgarian

Hindi

Portuguese

Catalan

Hmong Daw

Romanian

Chinese Simplified

Hungarian

Russian

Chinese Traditional

Indonesian

Slovak

Czech

Italian

Slovenian

Danish

Japanese

Spanish

Dutch

Klingon

Swedish

English

Korean

Thai

Estonian

Latvian

Turkish

Finnish

Lithuanian

Ukrainian

French

Malay

Urdu

German

Maltese

Vietnamese

Greek

Norwegian

Welsh

Haitian Creole

Persian

 

 

TRANSLATE with

COPY THE URL BELOW

Back

EMBED THE SNIPPET BELOW IN YOUR SITE


Enable collaborative features and customize widget: Bing Webmaster Portal

Back

带着疑问去思考,然后串联,进而归纳总结,不断追问自己,进行自我辩证,像侦查嫌疑案件一样看待技术问题,漆黑的街道,你我一起寻找线索,你就是技术界大侦探福尔摩斯