写在前边
- HashMap属于比较常用的数据结构了,面试过程中也经常会被问到,本篇就知识点,展开问答式分析,重点聊聊hash冲突、扩容死链、容量为2的n次方等问题~
1.7和1.8有什么不同
1.7是 数组+链表 1.8是 数组+链表【超过阈值会变成红黑树】
如何解决Hash冲突问题
扩容
条件
- 链表长度超过8
- 元素个数超过数组个数的75%
树化规则
条件
- 链表长度超过8
- 此时看看数组长度是否超过64,超过就进行树化,否则只是单纯扩容
为什么需要树化
其实一般正常的元素,都是不会超过阈值的,只有插入一堆重复的元素,hash值一样,才可能达到阈值,这个简称Dos攻击 而元素一旦多起来,链表查找的效率就远不及红黑树了
🤷♂️树化一定更好吗?
不是的,维护红黑树需要占用比链表更多的空间,而且当链表长度足够短的时候,链表查找的效率反而比红黑树更高??
为什么选择0.75和8
- hash 值如果足够随机,则在 hash 表内按泊松分布,在负载因子 0.75 的情况下,长度超过 8 的链表出现概率是 0.00000006,树化阈值选择 8 就是为了让树化几率足够小
退化规则
扩容的时候链表长度<=6
remove节点的时候
root、root.left、root.right、root.left.left 有一个为 null ,也会退化为链表(看的是移除之前的情况)
为什么需要二次哈希
先获得key的hashCode的值 h,然后 h 和 h右移16位 做异或运算。
实质上是把一个数的