HashMap常见面试题
感谢:https://blog.csdn.net/xiewenfeng520/article/details/107119970
1. HashMap是如何解决Hash冲突的?
使用链表存放hash值相等且内容不同,存放同一链表
2.HashMap的put方法的底层实现?
a. 判断key如果为空的情况下,存放数组0的位置
b. 默认HashMap初始容量为16,加载因子大小是160.75=12 每次狂容2倍
c. 根据key值计算hash值,存放在数组下标位置
d. 如果key相等,但是内容不等的情况下存放在同一链表中
e. 如果当前size>加载因子阈值,进行2倍扩容
ps:如果是1.8版本中链表长度如果大于8,转为红黑树结构
关于为什么要在8的时候转红黑树,这篇文章有详细的讲解
HashMap 链表长度超过8才转为红黑树?
3. HashMap为什么加载因子的值为0.75?
因为折中的方案,空间利用率高,冲突小,0.75最合适
4. HashMap1.7中数组扩容死循环的问题有遇过吗?
有,因为HashMap1.7数组的扩容的链表是头插法,在多线程的情况下会导致死循环的问题
5. HashMap根据key查询时时间复杂度是多少?
HashMap根据key可以直接计算index值,直接从数组中查询数据,分为两种情况:
如果index没有产生冲突,可以直接获取值,时间复杂度为o(1)
如果index产生了冲突,遍历链表,时间复杂度为o(n)
6. HashMap1.8改进了1.7哪些地方?
a. HashMap1.8链表采用尾插法,解决了1.7死循环的问题
b. 链表长度大于8时转换为红黑树
7.HashMap为什么需要引入红黑树?
如果index冲突过多,导致链表过长,因为链表时间复杂度为o(n),为了解决连表查询效率低的问题,这时候如果链表长度大于8且数组长度大于64的情况下将链表转给红黑树,这时候时间复杂度转为o(logn) 实际上转为红黑树的这种情况很少很少,具体原因上述文章中讲述的很清楚。
8. HashMap线程安全吗?有哪些替代方案?HashMap和HashTable的区别?
a. HashMap是线程非安全的,HashTable是线程安全的
b. HashMap允许使用null值(key和value)都可以,HashTable不允许null值(key和value都不可以)
虽然HashTable是线程安全的但是对于线程安全,建议使用ConcurrentHashMap 它也是线程安全的, 是分断锁的机制,效率要比hashtable要高