## HashMap的hash算法
hash源码如下
做了什么?
- 获取hash值
- hash值无符号右移
- 然后把前两步的结果做亦或运算
为啥这么做?
- 经过上边的操作,右移 和 亦或运算。得到的hash值二进制的高十六位和低十六位将都保留hash值的数字特征。
- 另外,也和hash寻址有关,按照正常的逻辑,我们想要把hash值对数组长度取模,然后当做数字下标。而源码进行了优化,通过 (n-1)& hash 值得到下标,其实一样的效果,这不过这样的效果更好一点 。
- 再根据上边的hash寻址,位移,和亦或,可以减少hash冲突。
## Hash碰撞怎么做(hash冲突)
链表+红黑树
如果元素的key的hash值相同,则使用一个链表来存放。链表查找一个元素的时间复杂度为 O(n),链表到达一定长度(8),则使用红黑树,红黑树寻找一个元素的时间的时间复杂度为O(logn)
## rehash 扩容
当存放的长度到达阈值以后,就要出发rehash,将原来的进行重新hash,判断hash值和新的数组长度与的结果,是否多了一个比特,如果没多则还是原来的位置,如果多了,则是原来的位置 + 原来的数组的长度,就是在新数组的下标位置。