论坛首页 Java企业应用论坛

从数据结构谈HashMap的实现

浏览 17421 次
精华帖 (0) :: 良好帖 (3) :: 新手帖 (17) :: 隐藏帖 (3)
作者 正文
   发表时间:2010-09-03  
我知道初始容量很重要, 但是虽然我没有看过HASHMAP的源码,我猜扩容的时候 也是浅复制吧 有那么大的损耗么~
0 请登录后投票
   发表时间:2010-09-03  
diferent 写道
我知道初始容量很重要, 但是虽然我没有看过HASHMAP的源码,我猜扩容的时候 也是浅复制吧 有那么大的损耗么~

扩容的时候以前的数据分布要重新分布
0 请登录后投票
   发表时间:2010-09-03  
J-catTeam 写道
ming123 写道
[quote="zhangshixi"]
3. HashMap中有加载因子loadFactor这个参数的定义,当HashMap中的元素个数超过数组大小*loadFactor时,就会进行数组扩容,loadFactor的默认值为0.75,这是一个折中的取值。也就是说,默认情况下,数组大小为16,那么当HashMap中元素个数超过16*0.75=12的时候,就把数组的大小扩展为 2*16=32,即扩大一倍,然后重新计算每个元素在数组中的位置,而这是一个非常消耗性能的操作,所以如果我们已经预知HashMap中元素的个数,那么预设元素的个数能够有效的提高HashMap的性能。

我之前也写过几篇类似的文章,可供参考:深入Java集合学习系列:HashMap的实现原理。



请问你,如何预设hashmap的个数??

在已知存入数据数目的情况下
将hashmap的值设置为
已知的数据*4/3+1这样
比如你的已知数目是12,12*4/3+1为17不会超过17的3/4。


修改一下 刚才看了源码,他会用int转型的 所以你要保证的是你的结果可以整除4的。
但是你自己也是可以修改这个扩容因子的。

 

预设HashMap的初始容量的情况,主要是你对所要存储的数据的数量可预知或者可预测的情况。

 

HashMap 包含如下几个构造器:

   HashMap():构建一个初始容量为 16,负载因子为 0.75 HashMap

   HashMap(int initialCapacity):构建一个初始容量为 initialCapacity,负载因子为 0.75 HashMap

   HashMap(int initialCapacity, float loadFactor):以指定初始容量、指定的负载因子创建一个 HashMap

 

HashMap的基础构造器HashMap(int initialCapacity, float loadFactor)带有两个参数,它们是初始容量initialCapacity和加载因子loadFactor

因此,当你在构造HashMap时,如果预知存储数据的数量,可使用稍大于存储数量/loadFactor转成int后的值来设置初始容量。以避免数量过多时,造成不必要的多次扩容。

HashMap的实现中,是通过threshold字段来判断HashMap的最大容量:

threshold = (int)(capacity * loadFactor); 
if (size++ >= threshold)     
    resize(2 * table.length);

 当你的初始容量不是2的n次幂时,HaspMap会主动帮你进行优化,你不必要去保证自己构造时传入的初始容量一定为2的n次幂,只要大于存储数量/loadFactor即可。这样做的原因我在上面已经分析的很清楚了,length总是 2 n次方时,h& (length-1)运算等价于对length取模,也就是h%length,但是&%具有更高的效率。HashMap保证底层数组的大小总是2的n次幂的代码如下:

int capacity = 1;  
     while (capacity < initialCapacity)  
          capacity <<= 1;  
 

 

 

 

0 请登录后投票
   发表时间:2010-09-07  
兰州,HashMap扩容的时候不是实际容量>=初始容量吧,貌似还有个加载因子这个东东。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics