java hashmap原理分析

/**
* 1、hashmap中维护了一个节点数组。
* 2、字符串的hashcode计算方法为h = 31 * h + val[i];
* 意思是把字符序列当成31进制的数值
* 3、put时,计算hash值 hash= h ^ (h >>> 16)
* 然后计算存放到数组元素的索引,i = (n - 1) & hash,其中n是数组的长度。
* 如果有冲突,那就用拉链法或者红黑树保存冲突的元素。
* 内部TREEIFY_THRESHOLD=8,put时一个节点冲突元素个数达到8个,就用红黑树节点。
* UNTREEIFY_THRESHOLD=6,remove时一个节点少于等于6个,就改成拉链法。
* 对put和remove采用双阈值的方式,防止频繁TREEIFY和UNTREEIFY操作,666!!!
* 4、get时,计算hash值 hash= h ^ (h >>> 16)
* 然后计算存放到数组元素的索引,i = (n - 1) & hash,其中n是数组的长度。
* 如果找到,就判断节点是拉链法的节点还是红黑树的节点。
* 接下来就是从链表或者红黑树中查找元素了。
*
* 冲突分析
* 产生冲突,即i = (n -1)&hash结果相同。
* 数组初始化长度为1<<4,即n = 16。
* 所以hash低4位相同就会产生冲突。
* 根据 hash= h ^ (h >>> 16),
* 如果 h 的低4位(低段)和h的高16位到高20位(高段) 异或结果相同,就会产生冲突。
* 其中的一种特殊情况是两个h的低段和高段对应相等。
*
* 另外一种考虑冲突的方式,是从字符串的hashcode h = 31 * h + val[i];入手
* 由于采用31进制,所以如果字符跨度超过31则可能不同的字符串hashcode相同。
* 比如有长度都为2的序列x1x2和y1y2,如果满足x1=y1-1,x2=y2+31,
* 那么这两个字符串的hashcode就冲突了。例如, “!!”和”“@”的hashcode都为1087。
* jdk8之前的hashmap,在冲突之后的解决方案是使用拉链法,jdk8已经改成拉链法和红黑树了。
* 所以,即使有冲突,检索的时间复杂度也是由O(1)变成了O(nlogn)。这个n是该节点冲突的个数。而且hashmap有resize机制和load factor控制,所以冲突的概率本来就不高。
* 一般情况下基本不需要考虑冲突问题了。
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值