面试官:
hashmap的底层数据结构是什么
小瑞:
底层是数组加链表,jdk1.8之后优化增加了红黑树
面试官:
什么情况下会有红黑树
小瑞:
当链表长度超过8时,会将链表转为红黑树
面试官:
hashmap的容量为什么是2的幂
小瑞:
因为要根据hash算法得到数据的下标,
为了实现高效的Hash算法,hashMap的发明者采用了位运算的方式。
如果不是2的幂,产生哈希碰撞的概率大,效率会变低。
(补充)公式:index = HashCode(Key) & (Length - 1)
以值为“book”的key来演示整个过程:
1.计算book的hashcode,结果为十进制的3029737,二进制的101110001110101110 1001。
2.假定HashMap长度是默认的16,计算Length-1的结果为十进制的15,二进制的1111。
3.把以上两个结果做与运算,101110001110101110 1001 & 1111 = 1001,十进制是9,所以 index=9。
可以说,Hash算法最终得到的index结果,完全取决于Key的Hashcode值的最后几位。
面试官:
hashmap扩容是怎么处理的
小瑞:
影响发生Resize的因素有两个:
1.Capacity
HashMap的当前长度。HashMap的长度是2的幂。
2.LoadFactor
HashMap负载因子,默认值为0.75f。
衡量HashMap是否进行Resize的条件如下:
HashMap.Size >= Capacity * LoadFactor
HashMap的Rezie不是简单的把长度扩大,而是经过两个步骤
1.扩容
创建一个新的Entry空数组,长度是原数组的2倍。
2.ReHash
遍历原Entry数组,把所有的Entry重新Hash到新数组。
为什么要重新Hash呢?因为长度扩大以后,Hash的规则也随之改变。
面试官:
jdk1.7与1.8在数据插入方式有什么区别
小瑞:
1.7是头插法,1.8是尾插法,将元素放到链表的尾部