📜  Java HashMap 中的负载因子示例

📅  最后修改于: 2021-09-03 13:41:52             🧑  作者: Mango

HashMap 是一个实现Java Collections Framework 的 Map 接口的类。 HashMap 最重要的特性是它具有恒定的检索插入时间性能。决定 HashMap 性能的两个因素是:

  • 初始容量
  • 负载系数

在我们解释什么是 HashMap 的负载因子之前,有必要了解它的结构。

HashMap 的节点包含键值对,很像 Map 中的节点。 HashMap 有包含节点的桶,一个桶可能包含多个节点。 HashMap 的基本结构如下:

HashMap的结构示意图

索引:是将key的hash值与数组大小减1后的按位AND运算得到的整数值。

其中 hashcode 是一个预定义的函数,它返回键的散列的整数值,ArraySize 是 HashMap 中的桶数。

Bucket :它是节点的 LinkedList 结构。

节点:它是HashMap的基本单元。它包含键值对和到下一个节点的链接。

声明 HashMap 对象的语法如下:

初始容量

初始容量本质上是 HashMap 中的桶数,默认情况下为2 4 = 16 。一个好的 HashMap 算法会将相同数量的元素分配到所有存储桶。

假设我们有 16 个元素,那么每个桶将有 1 个节点,任何元素的搜索都将通过 1 次查找实现。如果我们有 32 个元素,那么每个桶将有 2 个节点,任何元素的搜索都将通过 2 次查找实现。类似地,如果我们有 64 个元素,那么每个桶将有 4 个节点,任何元素的搜索都将通过 4 次查找来实现,依此类推。

正如您可以观察到的,当元素数量增加一倍时,查找增量增加 1,这对性能有好处。

但是当元素数量达到非常高的值时会发生什么,比如 10,000,在这种情况下,我们将需要 625 次查找。同样,如果元素数量为 10,00,000,我们将需要 62,500 次查找。如此大量的查找会降低 HashMap 的性能。这就是负载因子发挥作用的地方。

负载系数

Load Factor 是一个阈值,如果当前元素与初始容量的比值超过这个阈值,则容量增加,使得HashMap 的操作复杂度保持为O(1)。 O(1) 的操作复杂度的含义是指检索和插入操作需要恒定的时间。
HashMap 的默认加载因子是0.75f

我们如何决定何时增加容量?

让我们举个例子,由于默认的初始容量是 16,假设我们现在有 16 个桶。

以类似的方式,每次插入超过 0.75 的负载因子时,对于 get() {检索} 和 put() {插入} 操作的恒定时间性能,容量都会增加一倍。