模拟 HashMap 冲突
最近看 HashMap 的源码,其中相同下标容易产生 hash 冲突,但是调试需要发生 hash 冲突,本文模拟 hash 冲突。
hash 冲突原理
HashMap
冲突是 key 首先调用hash()
方法:
复制代码
然后使用 hash 值和 tab 数组长度做与操作:
复制代码
算出来的下标,如果一致就会产生冲突。
通过 ASKII 码获取单个字符
开始想到单字符,比如a、b、c、d、e
这类字符,但是如果一个一个试的话特别繁琐,想到了ASKII码
:
遍历1~100
的ASKII码
。通过ASKII码
获取单字符:
复制代码
通过str
获取下标,HashMap
默认长度为16
,所以n-1
为 15:
复制代码
获取发生 hash 冲突的字符
算出index
一致的话,就放在一个列表中。不同的index
放在HashMap
中,完整代码如下:
复制代码
输出结果:
复制代码
源码调试
根据上面算出来的结果,使用其中的一个例子:
复制代码
先添加数据:
复制代码
先添加1, A, Q
三个数据。然后添加Q
。
打开调式,定位到putVal
方法:
复制代码
在源码解析文章详解HashMap源码解析(下)中知道,发生 hash 冲突是会在上面代码的第16
行,一直for
循环遍历链表,替换相同的key
或者在链表中添加数据:
复制代码
调式:
会一直遍历for
循环,直到p.next==null
遍历到链尾,然后在链表尾部添加节点数据:
复制代码
总结
通过
(h = key.hashCode()) ^ (h >>> 16)
高位运算hash码
和(n - 1) & hash
哈希表数组长度取模,分析hash
冲突原理。通过
ASKII码
遍历获取字符串,获取发生hash冲突
的字符。调用
put
方法,调用hash
冲突源码。
评论