在读HashMap源码的时候,有些位运算的目标和原理不是很分明,顺便记下来以便日后温习应用。
1 为什么hashMap内hash办法会对原对象hash值右移16位?
`static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);//这里对key,hash值右移了16位
}`
hash值位int类型,长度位32bit,右移16位后再与本身的hash值进行与操作,会进步hash值计算方法的复杂度,进步hashMap中hash值的散列水平,使其更平均的散布。
2 扩容拆分链表时为什么是hash值与原有数组的大小进行并操作(寄存下标是等于对象hash值与现有数组长度减一进行取余的操作)?
`if ((e.hash & oldCap) == 0) {
if (loTail == null)
loHead = e;
else loTail.next = e;
loTail = e;
}`
此操作是为了确定链表的节点元素在新数组中的下标地位,若等于0则地位不变,如果不为0,则地位位当初所处的地位下标+原有数组长度,上面来剖析一下原理。
首先来明确一个概念,hashmap中元素的寄存地位与数组下标的关系是:

数组下标=元素的hash值&(数组长度-1)而且hashmap的长度肯定是2的n次方。那么原有数组长度的二进制数能够这样示意 1 0 0 0 0扩容后数组长度为                   1 0 0 0 0 0原有数组长度减一后为                 0 1 1 1 1现有数组长度减一后为               0 1 1 1 1 1那么原有数组中元素寄存地位下标只与后四位无关,扩容后只与后五位无关,那么,如果只与第五位进行与操作的话,就能够判断出该元素寄存地位是否须要扭转了。