HashMap中神奇的h & (length - 1)运算
2018-01-09 00:00
155 查看
众所周知,HashMap是基于Hash表的Map接口实现,HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。HashMap中主要是通过key的hashCode来计算hash值的,只要hashCode相同,计算出来的hash值就一样。但是知道了Hash值之后,又是怎么确定出key在数组中的索引呢?
根据源码得知如下方法
static int indexFor(int h, int length) { //根据hash值和数组长度算出索引值
return h & (length-1);
这样做有什么好处呢 ?
根据源码得知如下方法
static int indexFor(int h, int length) { //根据hash值和数组长度算出索引值
return h & (length-1);
这样做有什么好处呢 ?
1、保证不会发生数组越界
首先我们要知道的是,在HashMap,数组的长度按规定一定是2的幂。因此,数组的长度的二进制形式是:10000…000, 1后面有偶数个0。 那么,length - 1 的二进制形式就是01111.111, 0后面有偶数个1。最高位是0, 和hash值相“与”,结果值一定不会比数组的长度值大,因此也就不会发生数组越界。2、保证元素尽可能的均匀分布
由上边的分析可知,length一定是一个偶数,length - 1一定是一个奇数。假设现在数组的长度length为16,减去1后length - 1就是15,15对应的二进制是:1111。现在假设有两个元素需要插入,一个哈希值是8,二进制是1000,一个哈希值是9,二进制是1001。和1111“与”运算后,结果分别是1000和1001,它们被分配在了数组的不同位置,这样,哈希的分布非常均匀。那么,如果数组长度是奇数呢?减去1后length - 1就是偶数了,偶数对应的二进制最低位一定是 0,例如14二进制1110。对上面两个数子分别“与”运算,得到1000和1000。结果都是一样的值。那么,哈希值8和9的元素都被存储在数组同一个index位置的链表中。在操作的时候,链表中的元素越多,效率越低,因为要不停的对链表循环比较。相关文章推荐
- HashMap中(tab.length - 1) & hash的神奇之处
- hashmap 中hash函数h & (length-1)详解
- 神奇的位运算
- 异或运算的神奇运用
- 神奇的取反运算
- 神奇的位运算
- 神奇的异或运算
- 神奇:java中float,double,int的值比较运算
- 异或运算的神奇运用
- hashmap 中hash函数h & (length-1)详解
- 【leetcode】【Single Number题目】java 异或运算解决数字出现偶数次还是奇数次问题||HashMap
- zoj 3432 神奇的位运算。。
- 神奇的C语言二十一:谈谈位运算
- 算法之神奇的位运算
- JavaScript并行运算新机遇——Web Workers的神奇魔法
- 神奇的模运算
- 新手在写短信接口使用hashMap在位运算中遇到的问题
- NEFU 1317 神奇的开方运算(线段树)
- 位运算-Single Number III(只有两个不同的数字出现了一次,其余出现了两次,找出这两个数)
- 位运算小结2---计算两个无符号整数的平均值