为什么ArrayList以1.5的速度增长,但对于Hashmap来说,它是2?
根据Sun Java实现,在扩展期间,ArrayList的初始容量增长到3/2,而对于HashMap,扩展速率是两倍。这背后的原因是什么?
根据实现,对于HashMap,容量应始终处于两者的幂中。这可能是HashMap行为的一个原因。但在这种情况下,问题是,对于HashMap来说,为什么容量应该总是由两个组成?
根据Sun Java实现,在扩展期间,ArrayList的初始容量增长到3/2,而对于HashMap,扩展速率是两倍。这背后的原因是什么?
根据实现,对于HashMap,容量应始终处于两者的幂中。这可能是HashMap行为的一个原因。但在这种情况下,问题是,对于HashMap来说,为什么容量应该总是由两个组成?
增加 ArrayList 容量的昂贵部分是将支持阵列的内容复制到一个新的(更大的)支持阵列。
对于 HashMap,它正在创建一个新的支持数组,并将所有映射条目放在新数组中。而且,容量越高,碰撞风险越低。这更昂贵,并解释了为什么膨胀系数更高。1.5与2.0的原因是什么?我认为这是“最佳实践”或“良好的权衡”。
对于HashMap,为什么容量应该总是在两个的幂上?
我能想到两个原因。
您可以快速确定哈希码进入的存储桶。你只需要一个按位和,没有昂贵的模。int bucket = hashcode & (size-1);
假设我们的增长因子为 1.7。如果我们从大小 11 开始,则下一个大小将是 18,然后是 31。没关系。右?但是Java中字符串的哈希码是用31的质因数计算的。然后,字符串进入的存储桶仅由字符串的最后一个字符确定。再见,如果您存储的文件夹都以 结尾。例如,如果使用 的大小,则如果增加 n
,分布不会变得更糟。从大小到 ,桶中的每个元素现在都会转到 bucket ,或者 ,这取决于更高的数字。这就像把每个桶分成三块。因此,整数增长因子的大小将是首选。(当然,这一切都取决于你如何计算哈希码,但任意增长因子感觉并不“稳定”。hashcode%31
O(1)
/
3^n
3
9
2
2
5
7