1.key转换成hash
>>>表示无符号的右移:按照二进制把数字右移指定数位,高位直接补零,低位移除。
^(按位异或运算):运算规则:相同的二进制数位上,数字相同,结果为0,不同为1。
高16 bit 不变,低16 bit 和高16 bit 做了一个异或(得到的 hashcode 转化为32位二进制,前16位和后16位低16 bit和高16 bit做了一个异或)
public class HashMap<K,V> extends AbstractMap<K,V>implements Map<K,V>, Cloneable, Serializable {static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);}
}
2.hash转换成i
数组长度是2的k次方
hash & (length-1)运算等价于对 length 取模,也就是hash%length,但是&比%具有更高的效率。hash & (length-1) = hash%length。
i = hash & (table.length - 1)
3.总结
- 数组长度是2的n次幂,这样hash & (length-1) = hash%length,&比%具有更高的效率;
- 当我们根据key的hash确定其在数组的位置时,如果n为2的幂次方,可以保证数据的均匀插入,如果n不是2的幂次方,可能数组的一些位置永远不会插入数据,浪费数组的空间,加大hash冲突。
- 求key的hash的时候,前16位和后16位低16 bit和高16 bit做了一个异或,这样可以尽量减少hash冲突