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

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() implementationNote
Booleanreturn  1231 or 1237;1231 和 1237 是两个相对较大的质数,请看这里: http://stackoverflow.com/questions/3912303/boolean-hashcode
Bytereturn 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位的信息,这就不是好的implementation
Floatreturn 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()方法,具体方法请看

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

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值