Thinking in Java之HashMap源码分析(三)

2014-11-24 11:22:29 · 作者: · 浏览: 17
值的情况,我们就不在详述了,读者朋友可自行参阅jdk源码。

接下来进入getEntry(key)方法体里面去。


[java]
final Entry getEntry(Object key) {
int hash = (key == null) 0 : hash(key);
for (Entry e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
}
return null;
}

final Entry getEntry(Object key) {
int hash = (key == null) 0 : hash(key);
for (Entry e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
}
return null;
} 嘿,这不和存储的方式有些相似吗,由hash的到索引,如果索引位置为空,就不存在此key

values返回的就是空。如若索引位置不为空,该位置下可能是一条链,找到这条链里面可key的

hash相同的key,返回其对应的values。呵呵,取元素的方法是否简单多了呢?


5、删除元素

对于删除元素的原理和上述都是差不多的,这里笔者也就不解析了嘛。


6、HashMap优化
容量调整

对于容量的调整,这个是HashMap较为重点的部分,仔细想想看,对于hashMap我们应该

做的是尽量的避免hash冲突 ,此时对于数组的扩容就应该考虑了。不过一个蛋疼的问题也就

出现了,由于新数组的容量变了,原数组的数据就必须重新计算其再数组中的位置,并放入

这就是resize。同时这也是最消耗性能的地方。

那么在什么情况下对HashMap进行扩容呢?一般当HashMap的元素个事超过数组大小*

*loadFactory的时候,就会进行扩容,而loadFactor就是上文所说的负加载因子。默认值为0.75

例如数组空间为16,当元素超过16*0.75=12的时候就把数组大小扩为2*16=32,然后resize

这是一个非常消耗性能的是,因此如果我们预料到HashMap中元素的个数,这就能够有效的

提高hashMap的性能。

负载因子
为确定何时调整大小,而不是对每个存储桶中的链接列表的深度进行计数,基于hash的

Map使用一个额外的参数并粗略计算存储桶的密度。Map在调整大小之前,使用名为LoadFactory


的参数指示Map将承担的“负载”量,即它的负载程度。loadFactory、map大小、容量之间关系:

如果(负载因子)x(容量)>(Map 大小),则调整 Map 大小