Java中的HashMap实现.桶指数计算如何工作?

gnr*_*ddy 46 java hashmap

我正在研究HashMapJava 中的实现,并且一度陷入困境.功能
是如何indexFor计算的?

static int indexFor(int h, int length) {
   return h & (length-1);
}
Run Code Online (Sandbox Code Playgroud)

谢谢

Pet*_*ček 102

散列本身是通过hashCode()您尝试存储的对象的方法计算的.

你在这里看到的是计算"桶"来存储基于哈希的对象h.理想情况下,为了避免碰撞,你h可以获得与最大可实现值相同数量的桶- 但这可能对内存要求太高.因此,您通常会有较少数量的铲斗,存在碰撞危险.

如果h是1000,但在底层数组中只有512个桶,则需要知道放置对象的位置.通常,mod操作就h足够了,但这太慢了.鉴于HashMap底层数组总是有多个桶的内部属性2^n,Sun的工程师可以使用它的想法h & (length-1),它用一个由所有数字组成的数字进行按位AND1,实际上只读取n散列的最低位(这是一样的做h mod 2^n,只是快).

例:

     hash h: 11 1110 1000  -- (1000 in decimal)
   length l: 10 0000 0000  -- ( 512 in decimal)
      (l-1): 01 1111 1111  -- ( 511 in decimal - it will always be all ONEs)
h AND (l-1): 01 1110 1000  -- ( 488 in decimal which is a result of 1000 mod 512)
Run Code Online (Sandbox Code Playgroud)

  • _Very_很好解释.我印象深刻. (5认同)
  • 它现在有意义吗,还是我应该详细说明内部结构? (4认同)
  • 这是否意味着如果最低的 9 位左右一致,但较高的位不同,哈希桶可以包含具有不同“hashCodes”的键? (2认同)

Boh*_*ian 34

它不是计算哈希值,而是计算.

该表达式在使用时h & (length-1)略微有点,它就像一个位掩码,只返回低位,从而形成一个超快的变量.ANDhlength-1hh % length

  • 你能在这里解释这个计算吗? (3认同)
  • 这是否假设“长度”是 2 的幂? (3认同)
  • @LarsH 好吧,如果它是 2 的幂会好得多,然后您就可以清楚地切掉高阶位。碰巧的是,HashMap 的实现从大小 16 开始,并且在调整大小时确实乘以 2。如果不是 2 的幂,它仍然可以工作,但是您希望“长度 -1”尽可能多的位“打开”以平衡存储桶之间的传播 (2认同)