Java中的hashCode()是如何实现的?

来源:互联网 发布:jr史密斯cba数据 编辑:程序博客网 时间:2024/05/17 03:02
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() implementationNoteBooleanreturn  1231 or 1237;1231 和 1237 是两个相对较大的质数,请看这里: http://stackoverflow.com/questions/3912303/boolean-hashcodeBytereturn the byte value ranging from -128 to 127由于Byte类型的所有信息都存在了低32位中,所以直接返回wrapped的value (converted 成了int 以后的值)Characterreturn the character ASCII code由于Character类型的所有信息都存在了低32位中,所以直接返回wrapped的value (converted 成了int 以后的值)Shortreturn the short value由于Short类型的所有信息都存在了低32位中,所以直接返回wrapped的value (converted 成了int 以后的值)Integerreturn the int value直接返回wrapped的value (converted 成了int 以后的值)Longreturn (int)(value ^ (value >>> 32));由于最后的hashCode的类型是int,  而int只有32位,所以64位的Long值,要砍掉一半。为了不失去一半的信息,这个expression的意思是,会值的高32位和低32位的值进行exclusive OR的结果,这样就保证结果均会受前后32位的影响,不会丢失信息。如果直接把Long转成int, 那就会丢掉高32位的信息,这就不是好的implementationFloatreturn floatToIntBits(value);把float 转成bits, 具体的implementation是我不是太懂,大概是把32位的float 直接当成int输出来,不管那些位置信息,例如本来第31位是符号位,第23到30位代表的是指数,但转成int值后,这些值代表的意义都不存在了,仅仅作为普通的int数位。Doublebits = doubleToLongBits(value);

        return (int)(bits ^ (bits >>> 32));第一段code与 floatToIntBits(value) 一样

第二段code是与Long.hashCode()一样Strings[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-java
And also this: http://mindprod.com/jgloss/hashcode.html#OBJECT