您的位置:首页 > 其它

HashMap的工作原理

2014-12-18 13:49 113 查看
昨日面试被问及这个问题,无奈HashMap初学时虽然深入探索过,之后却并无实际应用到如此深入的原理,只是初步的使用,因此便磕磕碰碰。

问1:知道HashMap的工作原理么?

答:根据传入的key值保存key与value组成的Entry对象。

问2:那如果传入两个hashcode相同的对象会有什么问题吗?

答:应该没什么问题吧,只要键值不同。(这里由于基本功不够扎实深入,引发了底气不足与肾虚)

问3:那传入两个hashcode相同的键对象呢?

问到这里我便有些虚的很了,由于并无验证过,我便单单回答出“若键的hashcode相同,但equals方法比较不同,就是两个值,若equals相同,就覆盖值了!”

于是我陷入了一个误区,这个误区来源于初学时一句深刻脑海的提醒:“要重写equals方法,务必要相应修改hashcode方法。”我理所当然的认为他们对等了!

其实在HashMap中,调用put方法传入键值对时,会根据key值的hash来计算存储的bucket位置,找到位置后将键值对作为Entry对象存储进去(注意是键值对都存储

进去,如果单单说值存储进去,那就错了!)而当调用get方法取值的时候,HashMap又会根据传入的键值计算hash找到对应的backet位置,你以为找到就

结束了么?你以为接下来就可以取了么?你太天真了!!!找到位置后它竟然又比较了key的hash值、key的内存地址或者equals方法(从这一方面来说我还是

回答对了的!)如果匹配到了,才取出来,如果比较了发现是两个不同对象呢(也就是说键的hash不同、键的内存地址或者equals方法返回不同),不用担心,

当你存入相同hash却不同值的对象时,它就给你安然的放到了准备好的backet里的Entry对象的next字段,没错,这next字段也是Entry!!!

public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
<span style="background-color: rgb(255, 0, 0);">e = e.next</span>) {
Object k;
if (<span style="background-color: rgb(255, 102, 102);">e.hash == hash && ((k = e.key) == key || key.equals(k))</span>)
return e.value;
}
return null;
}所以,hash相同?没关系,只要equals方法和内存地址不同,无所谓,只不过都挤在一块地方而已,取出来的时候该取谁还取谁!
还有其中夹杂的小问题:HashMap或者其他容器类如何打破数组固定长度的限制做到可扩容的?

很简单啊,看到快满了,再弄个更大的空间,把原来的都拷贝过去啊!!!就这么简单啊!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: