模拟 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冲突源码。









评论