JDK之HashMap中的indexFor(int h, int length)方法

今天看到了HashMap,发现其中有一个方法很奇怪,叫indexFor(int h, int length),这个方法返回的是某个hashcode对应到hash table的下标位置,代码是这么实现的:

static int indexFor(int h, int length) {
        return h & (length-1);
    }

看了半天才搞懂为什么这么写,其实HashMap中放数据的还是数组,当往map里put值时就是向数组中添加数据,只不过数据的位置时根据put的key来计算的。之前学hashtable的时候计算位置都是用hashcode%length的。但是HashMap中却不是这么做的。

我们假设现在hashmap的length为16,第一个hashcode的值为7.,那么根据上面的代码,计算过程应该是:

7&(16-1)

转换成二进制来计算就是:

0111

   &

1111

计算的结果为111,也就是7,我们会发现这个值与7%16的结果是一致的。让我们再测试一个hashcode为33。

二进制的计算过程是:

100001

    &

001111

计算结果为000001,这与33%16结果又是相同的。

经过几次模拟计算可以发现,length-1的二进制值中每一位都是1,并且HashMap中保证了map的长度永远是2的N次方,而2的N次方-1的值的二进制每一位都是1.。所以当我们拿hashcode的值来计算的时候,如果hashcode二进制位数是小于等于length-1的二进制位数,那么与计算结果就是hashcode的值,如果前者位数大于后者位数,则与计算时会将多出来的位与0相与,则结果必然时0,这就导致超出位的值被省去了,身下的值也就是hashcode%llength的值了。至于为什么不直接用hashcode%length,是因为位运算要比模运算快一些。

解释到这里应该已经清楚这行代码的意思了,在这里不得不感叹,JDK的作者水平还是高,想法已经不是在如何实现上了,而是怎么实现效率更高。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值