HashMap扩容中的模运算

Posted by Tenghuan He on March 23, 2018

JavaHashMapresize()方法有如下说明

Initializes or doubles table size. If null, allocates in accord with initial capacity target held in field threshold. Otherwise, because we are using power-of-two expansion, the elements from each bin must either stay at same index, or move with a power of two offset in the new table.

在容量扩大一倍之后重新计算哈希,元素的下标要么保持不变,要么在新的table中移动2^n(实际上也是旧的容量大小)位。

假设table当前容量为2^n,某个元素的哈希值为h

  • 扩容之前,下标的值相当于取h的低n位;
  • 扩容之后,容量变为2^(n+1),下标的值相当于取h的低n+1位。

因此有:

  • 如果h的第n+1位为0,则扩容之后,该元素在table中的下标位置不变;
  • 如果h的第n+1为为1,则扩容之后,该元素在table中的下标位置往后移动2^n个位置;

在JDK1.8的实现中,优化了高位运算的算法,通过hashCode()的高16位异或低16位实现的:(h = k.hashCode()) ^ (h >>> 16)