【问题标题】:HashMap Implementation questionHashMap 实现问题
【发布时间】:2025-12-03 15:35:01
【问题描述】:

HashMap 包含一个哈希表,它是一个保存值的数组

据我所知,哈希表有一个初始大小,但在多次调用 put() 后它会增加(取决于负载因子)

无论如何,我想知道在更改哈希表的大小后如何找到值,因为我知道为了计算特定键的 has 代码,您可以使用表的大小

例如键*prime%size

那么它是如何工作的呢?

【问题讨论】:

    标签: java hash implementation hashmap


    【解决方案1】:

    Visage 总体上回答了这个问题:从键计算的哈希值通过以映射的实际大小为模展开它们映射到存储桶,并且当调整映射大小时,所有元素再次分布在新范围内桶数。

    然而,从 Java 1.4 开始,幕后发生了一些值得了解的事情。首先,在传统的哈希映射中,大小是理想的质数,因为这有助于将元素更均匀地分布在桶的范围内。但是,在 Java 1.4 HashMap 中,大小始终是 2 的幂!这会使标准分布表现得非常糟糕 - 然而,在这个实现中,散列值在内部使用一种非常快速的算法来重新散列以平滑分布。

    Java 专家时事通讯,问题5454b 中的更多详细信息。

    【讨论】:

      【解决方案2】:

      因为密钥通常用于定位您的值所在的 bin。重新分配不会影响这一点,因为所有对象都会根据新的大小重新分配到新的 bin。

      【讨论】:

      • 哦,我明白了,你说在增加大小之后,你会遍历所有值并重新分配它们?
      • 不,HashMap 实现可以。
      【解决方案3】:

      如果您查看addEntry(..) 方法的代码,您会看到:

      if (size++ >= threshold)
         resize(2 * table.length);
      

      在调整大小时,会调用transfer(..) 方法,该方法:

      将所有条目从当前表转移到新表。

      【讨论】:

      • 它是如何回答问题的?
      • 最后一部分(在最初的几秒钟后添加)部分。