HashMap发生hash冲突处理原理
这两天一直在磕HashMap的源码,对于面试问题中经常问到如何处理Hash碰撞,
很多回答都说得太官方了,不容易理解,现在我用大白话的方式来解释一下,什么是哈希冲突
如果对HashMap不熟悉的,可以先去了解一下HashMap的实现原理,我这里就不多讲了哈
首先我们来看一下HashMap的put操作
当我们调用put
存值时,HashMap
首先会调用Key
的hash
方法,计算出哈希码,通过哈希码快速找到某个存放位置(桶),这个位置可以被称之为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 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步