HashMap为了存取高效,要尽可能较少碰撞,就是要尽可能把数据分配均匀,每一个链表长度大体相同。算法
关键就在于把当前数据存放到哪个桶中,这个算法就是取模运算。优化
假设:源码
length:HashMap的容量hash
hash:当前key的哈希值效率
取模运算为 hash % length二进制
可是,在计算机中,直接取模运算的效率不如位运算(&),什么是位运算?就是对于二进制数据的按位运算,1和1才得1,其余都得0,好比:1011 & 1100 = 1000链表
sun公司的大牛们发现,当容量为2的n次方时,hash & (length - 1) == hash % length ,因而就在源码中作了优化,经过 hash & (length - 1) 来替代取模运算,而前提就是容量必须为2的n次方。这样作的好处在于:数据
1. 提升操做运算效率(位运算效率 > 取模运算效率)查询
2. 减小碰撞,数据均匀分布,提升HashMap查询效率计算机
为何能够减小碰撞?举个例子,如今两个hash分别是2和3,:
好比 length 为 9 的状况:3&(9-1)=0 2&(9-1)=0 ,都在0上,碰撞了;
好比 length 为 8 的状况:3&(8-1)=3 2&(8-1)=2 ,不一样位置上,不碰撞;