【问题标题】:Why is resize implemented the way it is?为什么按原样实施调整大小?
【发布时间】:2014-02-12 22:29:58
【问题描述】:

在添加新的键值对时,我有几个关于重建 HashMaps 的问题。我将根据这些事实提出问题(它们对于 Oracle JVM 是正确的,不确定它们对于其他 JVM 是否正确):

  1. 每次当您将 HashMap 增长到大于阈值(阈值 = loadFactor*numberOfEntries)时,调整大小重建 HashMap 以获得更大的内部表数组。新创建的 Entry 放在哪个桶中并不重要 - Map 仍然会变大。即使所有条目都进入一个存储桶(即它们的密钥hashCode() 返回相同的数字)。
  2. HashMap 在删除数据时不会缩小。即使从HashMap 中删除所有键,它的表的内部大小也不会改变。

现在问题:

  1. 这些事实是否正确?

如果是,那么:

  1. 为什么以这种方式实现调整大小?即使显然没有必要,是否也打算增加内表?还是错误?
  2. 为什么不收缩?

【问题讨论】:

    标签: java dictionary hashmap resize


    【解决方案1】:

    是的,这些事实是正确的。

    1. 检测是否“显然没有必要”会花费很多时间,而且几乎总是多余的,因为所有键都具有相同哈希码的情况很少见。简而言之,您为每个人 支付了大量费用(跟踪一个特定哈希码的常见程度),只是为了在极少数情况下节省一些工作,这最终会花费比节省更多的成本。
    2. 因为移除是一种不太常见的操作,并且通常会在重新填充地图之后进行。如果您想使用较小的表格重新开始地图,您可以将其分配给 new HashMap 并让旧表格被垃圾回收。

    【讨论】:

    • 哇,这很合理,谢谢!我可以再问一个吗?为什么添加表桶时不能增长hashmap,而添加条目时不能增长?
    • 这个问题没有意义。 “添加表桶”是“hashmap 增长”的同义词。哈希映射的用户无法“添加表桶”;当有更多条目时添加表桶。
    • 抱歉,“添加了表桶”我的意思是“已填充内部表数组”。我的意思是,当所有表数组元素都不为空(或其中的一小部分)时,我们为什么不调整地图的大小?
    • 通过在添加条目时调整大小,我们实质上是在每个桶的平均条目数超过一定数量时调整表的大小。在实践中发生的情况是,原始表中的每个存储桶都被拆分为新表中的两个存储桶,(平均)一半在一个新存储桶中,一半在另一个存储桶中。有多少桶是非空的并不重要,与每个桶的平均条目数无关。
    猜你喜欢
    • 2015-05-04
    • 2015-03-18
    • 2015-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-13
    相关资源
    最近更新 更多