HashMap集合在默认情况下的初始容量被设置为16,而在我们通过key去计算哈希值(索引值时)计算一般采用取余运算为key%(length-1)但这样在计算机中计算效率比较低,所以我们采用位运算来计算索引值,key&(length-1)这两种计算方式并无太大区别,只是相对于计算机组成原理来说位运算的效率要比取余运算的效率高。
接下里说一下为什么HashMap的容量要始终保持在2的n次幂的原因:
我们在计算哈希值时发生哈希碰撞是不可避免的,但是怎样才能减少哈希碰撞不让我们节点的链表或者红黑树过长以此来充分利用我们哈希数组的空间呢?我们可以通过位运算的例子得知。
位运算:都为1时则为1否则为0
一、哈希数组长度为偶数时
1、key值为3,数组长度为8;计算方式key&(length-1)
00 00 00 11
00 00 01 11 &
——————
00 00 0 0 11 ==3
————————————————————————————————————————
2、key值为4,数组长度为8;计算方式key&(length-1)
00 00 01 00
00 00 01 11 &
——————
00 00 0 1 00 ==4
二、哈希数组长度为奇数时
————————————————————————————————————————
1、key值为3,数组长度为9;计算方式key&(length-1)
00 00 00 11
00 00 10 00 &
——————
00 00 00 00 ==0
————————————————————————————————————————
2、key值为2,数组长度为9;计算方式key&(length-1)
00 00 00 10
00 00 10 00 &
——————
00 00 00 00 ==0
————————————————————————————————————————
由此我们可以看出当哈希数组长度为奇数时是极易发生哈希碰撞,导致我们的数组空间不能被充分利用且链表或红黑树过长,降低查找的效率而哈希数组长度为偶数时发生哈希碰撞的概率是比较小的,所以数组长度在考虑空间和效率两个层面上容量必须为2的次幂