文章目录
1. HashMap的组成?
答案:使用的是数组+链表+红黑树;
2. HashMap的构造函数,传入的参数一定是2的指数次幂?
答案:若传入的不是2的指数次幂,在put
元素对的时候,会修改HashMap的容量为大于设置的容量的最小的2的指数次幂;
eg: 1. 我们传入对的是13, 那么大于13的2的指数次幂是16; 2. 传入的是7,则大于7的2的指数次幂是8;
3. 为什么HashMap容量一定要是2的指数次幂?
答案:
1. 因为效率:因为,通过索引的hash和数组的长度进行取余,得到元素存储的位置,速度特别慢;而使用位运算则是直接操作底层的二进制,较快一些。<当length为2的指数次幂时:hash%length == hash&(length - 1);>
2. 因为可以保证取余得到的数值在范围之内;任何hashCode & length - 1; 得到的值一定在(0 - (length-1))中。
4. 为什么HashMap的扩容因子是0.75?
答案:是在空间和时间的复杂度上做了取舍而得;若取0.5,则查询速度较快(在数组中查询),会快速扩展数组大小;若取1,则查询速度较慢(在链表或是红黑树中查询),可以充分的利用完了空间再次扩容,但是也容易导致hash碰撞增多,从而放入到了链表或是红黑树中。
5. 链表大于8时,才转换为红黑树?
答案:使用了泊松分布的概率统计,在0.75的扩容因子下,能在同一个位置发生Hash碰撞的概率,若发生了8次,也就达到了亿分之一的概率。因此,只有这个时候,才需要转换为红黑树。
6. HashMap(jdk1.7)多线程下,put的时候会死锁?
答案: 在put的时候,会判断当前数组大小是否需要扩容;扩容的时候(当把老数组,放到新的数组时),会产生一个链表环的问题;
7. HashMap(1.8),如何解决put死锁?
答案: 使用高低位指针,保证数据位置的正确,拆分到不同的位置上,而不是像1.7中,还是放在一个hash位置上;而且,也不需要再进行rehash;