Hellooo,long time no|

fengzeng

园龄:4年10个月粉丝:17关注:5

HashMap发生hash冲突处理原理

这两天一直在磕HashMap的源码,对于面试问题中经常问到如何处理Hash碰撞,
很多回答都说得太官方了,不容易理解,现在我用大白话的方式来解释一下,什么是哈希冲突
如果对HashMap不熟悉的,可以先去了解一下HashMap的实现原理,我这里就不多讲了哈

首先我们来看一下HashMap的put操作

当我们调用put存值时,HashMap首先会调用Keyhash方法,计算出哈希码,通过哈希码快速找到某个存放位置(桶),这个位置可以被称之为bucketIndex,但可能会存在多个元素找到了相同的bucketIndex,有个专业名词叫碰撞,当碰撞发生时,这时会取到bucketIndex位置已存储的元素,最终通过equals来比较key是否为同一对象,如果是,则使用新Value值替换旧Value值,并返回旧Value值,如果不是,则把新的键值对<K, V>存放到bucketIndex位置。通过下面的流程图来梳理一下整个put过程。

现在我们知道,执行put方法后,最终HashMap的存储结构会有这三种情况,我们当然期望情形3是最少发生的(效率最低)。到目前为止,我们了解了两件事:

  • HashMap通过键的hashCode来快速的存取元素。
  • 当不同的对象发生碰撞时,HashMap通过单链表来解决,将新元素加入链表表头,通过next指向原有的元素(俗称拉链法)。

get操作就不讲了吧,逆向思维,怎么发生碰撞存,就怎么发出碰撞取

PS:最后补充一下,JDK1.7和JDK1.8 HashMap都做了一点优化

  • 1.7版本没有红黑树,发生冲突是把新元素插在头部(俗称头插法)
  • 1.8引入了红黑树,红黑树的插入和查询复杂度都是O(logn),这也是链表转红黑树的判定界限,1.8用的尾插法,貌似就这些了

本文作者:fengzeng

本文链接:https://www.cnblogs.com/Fzeng/articles/15068647.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   fengzeng  阅读(470)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起