【问题标题】:Confused about the load factor for the hashtable with collisions对带有冲突的哈希表的负载因子感到困惑
【发布时间】:2017-04-26 16:27:05
【问题描述】:

我对此类哈希表的负载因子感到困惑。
我知道,为了计算负载因子,我们需要将条目数除以我们拥有的插槽数,当负载因子达到 0.75 时,它必须重新散列。

那么,这个哈希表的“整数数量”是多少?这些键占用的键总数或索引总数。

因为如果它是键的总数,那么重新散列的意义何在?这只会浪费空间和时间。
如果它是仅占用索引的总数,那么负载因子将是 2/5 = 0.4?

【问题讨论】:

  • 条目的数量是键的数量,是的,因为每个键都有一个且只有一个关联值,一个条目是一个键/值对。对这样的map进行rehash的目的正是为了避免这种损害map性能的长链表,并更好地在桶之间分配条目。理想的分布是每个桶只有 0 或 1 个条目。
  • 但是当这种冲突发生时,重新散列不会有帮助,对吧?只有改变 hashFunction 才有效?
  • 没有。举个简单的例子,地图有 3 个桶,使用哈希码的简单模数来选择桶。假设地图中有 0、3 和 6。它们都将在桶 0 中,因为 0 % 3 == 0、3 % 3 == 0 和 6 % 3 == 0。现在让我们重新散列,并改用 7 个桶。现在 0 % 7 == 0,所以第一个键进入桶 0。3 % 7 == 3,所以 3 最终进入桶 3。6 % 7 == 6,所以键 6 进入桶 6 . 并且密钥现在理想地分布在存储桶中。

标签: java hashmap hashtable hashcode


【解决方案1】:

条目数是映射中键值映射的数量,由 https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#size-- 或者,Set 返回的元素数 https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#entrySet--

这符合我们对什么是映射(键值对的集合)的直觉,因此每一对都是一个条目。

根据https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html,条目数与负载因子fac(任意参数)和容量cap(当前桶数)的乘积进行比较。

您认为“当负载系数达到时”,但这是不正确的。施工后荷载系数不变。默认为0.75,几乎可以满足所有用途。

想想threshold 产品threshold = fac * cap;。 阈值仅在cap 更改时更改,因为fac 不会更改。

一直在变化的是nentries,即当前地图中的条目数。

(我只是编造变量名来简化这个答案。它们与实际的 Java API 源代码无关。)

您的图表显示了五个桶,所以threshold = (int)(0.75 * 5)3

重新哈希的决定是if (nentries >= threshold)。您的图片中有十个条目,所以是的,该地图需要重新散列。实际上,它会在第三个条目上重新散列,将cap 增加到大约十个条目,具体取决于实现。在第八个条目上,容量将增加到二十个,因此十个条目将小于新阈值threshold = 0.75 * 2016

【讨论】:

  • 这有点令人困惑!由于根据其他文章,负载因子=条目数/插槽数。在那个特定的例子中,它应该是 2,不是吗?
猜你喜欢
  • 2015-06-29
  • 2010-10-19
  • 2016-03-14
  • 2023-04-08
  • 2023-03-09
  • 2016-05-03
  • 1970-01-01
  • 2016-10-04
  • 1970-01-01
相关资源
最近更新 更多