hashMap中用了大量的位运算来优化,提高效率
初始化容量
最大容量
计算哈希桶索引
使用与操作来代替取余
num % length优化为num & (length - 1)
length 为 2 的 n 次幂时,转换为二进制,最高位为 1,其余位为 0;length-1 则所有位均为 1。1 和另一个数进行与操作时,结果为另一个数本身,另一个数的高位被截取,结果范围为 0 ~ length - 1,和取余操作结果相等。
那么桶数为什么必须是 2 的次幂?
如果不为2的次幂,某一位为0,而0和任何数与运算都为0,会造成单数桶的空间浪费掉。
hash方法
当key不为空时计算key的hashCode,然后用hashCode和hashCode无符号右移16的值进行异或运算
无符号右移和异或操作的主要目的是为了让生成的哈希值尽量均匀
1、为什么hashCode无符号右移16?
计算桶位置时会hash(key) % length,用hash和哈希桶数取余
通常哈希桶数不会特别大,绝大部分都在 0 ~ 2的16次幂 这个区间范围内,也即是小于 65536。因此哈希结果值 hash 再和 length 进行与操作时,hash 的高 16 位部分被直接舍得掉了,未参与计算,为了让高16的也能参与运算,所以用h>>>16获取高16位在于hashCode异或运算
2、为什么异或运算,相对于与和或运算,0 和 1 有均等的机会
指定初始化容量
通过5 次无符号右移和或操作,目的是将cap每一位都变为1,最后在+1则得到最近的一个2的次幂
一开始减一是因为如果cap一开始就是2的次幂,无符号右移和或操作后,所得结果是 cap 的 2 倍