为什么resize的方式实现?
在添加新的键值对时,我有几个关于重建HashMaps
问题。 我将根据这些事实提出问题(它们适用于Oracle JVM,不确定它们是否适用于其他JVM):
- 每次当HashMap大于阈值(阈值= loadFactor * numberOfEntries)时,resize重建
HashMap
以使内部表数组更大。 新创建的条目放在哪个桶中无关紧要 – 地图仍然会变大。 即使所有条目都进入一个桶(即它们的密钥’hashCode()
返回相同的数字)。 - 删除数据时,
HashMap
不会缩小。 即使从HashMap
中删除了所有键,它的表的内部大小也不会改变。
现在的问题是:
- 这些事实是否正确?
如果是,那么:
- 为什么resize这样实现? 即使显然没有必要,是否有意扩大内桌? 还是个bug?
- 它为什么不收缩?
是的,这些事实是正确的。
- 检测它是否“显然没有必要”将花费大量时间,并且它几乎总是多余的,因为所有密钥具有相同哈希码的情况很少。 简而言之,你需要支付大笔费用(跟踪一个特定哈希代码的常见程度),以便在极少数情况下保存一些工作,最终会花费超过它的成本。
- 因为删除是一种不太常见的操作,通常会重新填充地图。 如果要使用较小的表启动映射,可以将其分配给
new HashMap
并让旧的new HashMap
进行垃圾收集。