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也不一样,我写了如下的总结:
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()方法,具体方法请看
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