初始容量和负载因子是影响HashMap
性能的两个参数。默认负载系数 (.75
) 在时间和空间成本之间提供了良好的折衷。较高的值会减少空间开销,但会增加查找成本。
当一个项目被添加到 时,它会根据其派生的值和 的存储桶大小HashMap
分配给存储桶。要识别任何的桶,哈希映射使用并执行一些操作:hashCode
HashMap
key.hashCode()
Bucket (index) = HashMap.indexFor(HashMap.hash(key.hashCode()),
entryArray.length)
当哈希图中的条目数超过负载因子和当前容量的乘积时,哈希图被重新哈希(内部数据结构被重建),使得哈希图大约有两倍的桶数。
当您重新散列并将所有内容移动到新位置(存储桶等)时,旧元素也会再次重新散列并根据其新哈希码存储在新存储桶中。分配用于存储元素的旧空间被垃圾收集。
如果两个线程同时发现现在HashMap
需要重新调整大小并且他们都尝试重新调整大小可能会导致HashMap
.
在重新调整大小的过程中HashMap
,存储在链表中的存储桶中的元素在迁移到新存储桶期间会按顺序颠倒,因为javaHashMap
不会在尾部附加新元素,而是在头部附加新元素以避免尾部穿越。如果发生竞态条件,那么您最终将陷入无限循环。
我有以下问题:
- 为什么迁移到新bucket时每个bucket的链表顺序颠倒了?
- 竞争条件如何导致无限循环?
- 增加桶的数量如何减少查找等待时间?
- 重新散列后在同一个桶中的元素仍然会在同一个桶中吗?