Java 哈希桶的数量

Java 哈希桶的数量,java,hashmap,Java,Hashmap,文件中提到: 初始容量只是创建哈希表时的容量 容量是哈希表中的桶数 现在假设初始容量为16(默认值),如果我们继续向100个添加元素,hashmap的容量为100*loadfactor 哈希桶的数量是100还是16 编辑: 从解决方案中我读到:bucket不仅仅是添加的元素。 从这个角度来看:如果我们添加字符串作为键,我们将得到一个元素/桶,导致大量的空间消耗/复杂性,我的理解是对的吗 既不是100桶也不是16桶。很可能会有256个存储桶,但文档并不能保证这一点 从: 负载因子是在自动增加哈

文件中提到:

  • 初始容量只是创建哈希表时的容量
  • 容量是哈希表中的桶数
现在假设初始容量为16(默认值),如果我们继续向100个添加元素,hashmap的容量为100*loadfactor

哈希桶的数量是100还是16

编辑:
从解决方案中我读到:bucket不仅仅是添加的元素。
从这个角度来看:如果我们添加字符串作为键,我们将得到一个元素/桶,导致大量的空间消耗/复杂性,我的理解是对的吗

既不是100桶也不是16桶。很可能会有256个存储桶,但文档并不能保证这一点

从:

负载因子是在自动增加哈希表容量之前允许哈希表达到的满度的度量。当哈希表中的条目数超过加载因子和当前容量的乘积时,哈希表将被重新格式化(即,重建内部数据结构),以便哈希表的存储桶数大约是存储桶数的两倍

(强调矿山)

因此,如果忽略上面的“近似”一词,我们就可以确定,每当哈希表满了75%(或在构造函数中指定的任何加载因子),哈希桶的数量都会加倍。这意味着每当插入第12、24、48和96个元素时,存储桶的数量都会翻倍,总共留下256个存储桶

但是,正如我在文档片段中所强调的,这个数字大约是以前大小的两倍,因此可能不完全是256。事实上,如果将第二个到最后一个加倍替换为稍大的增加,则最后一个加倍可能永远不会发生,因此最终哈希表可能小到134个桶,或者可能大于256个元素

注意:我得到了134这个数字,因为它是最小的整数
N
,因此
0.75*N>100

从您的链接:

当哈希表中的条目数超过负载因子和当前容量的乘积时,通过调用rehash方法,容量大约会增加一倍

这意味着如果我们有初始容量16,当它超过时,容量将增加32,下次增加64,以此类推

在您的情况下,您将添加100个。因此,当您到达第16个号码时,大小将被添加32,因此现在总大小为48。再次添加,直到第48个数字,现在大小将增加64。因此,在您的情况下,桶的总大小是112。

每个实际项目至少有一个桶。如果添加的项目超过16个,则必须调整表的大小并重新设置其大小

现在假设初始容量为16(默认值),如果 将元素添加到100个,hashmap的容量为100* 负荷系数

实际上它说:

如果初始容量大于最大条目数 除以负荷系数,将不会发生再灰化操作


也就是说,如果最多有100个项目,且容量为100/0.75=133,则不应发生重新散列。请注意,这意味着即使表未满,也可能需要在接近满时重新刷新。因此,使用默认加载因子设置的理想初始容量,如果您希望查看HashMap的源代码,我们将看到以下内容:

threshold = capacity * loadfactor
size = number of elements in the map

if( size >= threshold ) {
  double capacity
}
因此,如果初始容量为16,负载系数为0.75(默认值),则初始阈值将为12。如果添加第12个元素,容量将上升到32,阈值为24。下一步将是容量64和阈值48等

因此,对于100个元素,您应该有256个容量和192个阈值

请注意,这仅适用于标准值。如果您知道地图将包含的元素的大致数量,则应创建具有足够高初始容量的地图,以防止在容量增加时复制

更新:

关于容量的一个词:它始终是二的幂,即使您定义了不同的初始容量。然后,hashmap将容量设置为大于或等于提供的初始容量的最小2次方。

In

让我们试试。。hashmap的初始大小为16
默认负载系数是
0.75
,所以第一个阈值是12,所以增加12个元素的下一个容量将是。。 (16*2)=32
2st阈值为24,因此在添加第24个元素后,下一个容量将为(32*2)=64


等等

@Thomas谢谢你的回答……一个疑问……容量是否意味着“没有散列桶”?@jain007我还将引用doc:
…HashMap实例的“容量”(桶的数量).
-那么,是的,容量就是桶的数量。@Thomas那么12个元素的存在意味着什么?这是否意味着Hashmap有12个键,或者12个bucket至少映射了一个元素?@Piecuckherr我不确定是什么让你感到困惑,但我指的是映射中的元素,即映射到键的值(因此在某种意义上你可以说元素=键)。+1用于引用文档。只是一个旁注:从Java7源代码来看,它的容量似乎是原来的两倍(或者四倍或更多,当
putAll()
与大型映射一起使用时)-事实上,Bucket表上有这样一条注释:
长度必须始终是二的幂。
-AFAIK没有二的幂的近似值:)@Adam是我的猜测正确的:根据上面的讨论,HashBucket将保持大于hashmap中的键数,因此发生冲突的可能性应该为零,如果将diff整数作为键?@Naroji仅仅因为哈希表中的bucket比键多就不会导致冲突,即使所有键都是唯一的。在一些问题上我
When the number of entries in the hash table exceeds the product of the 
load factor and the current capacity, the capacity is roughly doubled by 
calling the rehash method.

threshold=product of the  load factor and the current capacity