1.hashMap HashTable hashSet 区别
2.hashMap为什么线程不安全。多线程下可能有哪些问题?
答案:
https://www.jianshu.com/p/e6367828631a
2个put会同时扩容造成死循环(链表有环)
可能有2个同时put,导致1个丢失,被后面的put覆盖了。一种情况是2个线程,1存1取,A刚存完key1value1,还没等B取值,A又存完key1value2,这样B取值只能取得key1value2,key1value1就丢失了
3. hashMap扩容机制?
答案:
https://www.cnblogs.com/williamjie/p/9358291.html
当hashMap中的元素个数超过数组长度*0.75的时候会进行扩容,并且都是按照2的倍数进行扩容,扩容的过程是有性能消耗的,因为原数组中数据必须重新计算其在新数组中的位置,并放进去,关于怎么计算数组中的位置,这里有个核心hash算法,hash算法的原则就是尽量在HsahMap的数组上均匀分布,减少碰撞,避免形成链表,节省查询元素的时间。 这个算法是根据 hashCode & (数组长度 - 1) 算得key得hashcode值,然后跟数组的长度-1做一次“与”运算(&),这里注意,数组长度只有是2的倍数的时候,不同的key计算出的index相同的几率较小,数据在数组上的分布就比较均匀,减少碰撞,提升查询效率。
4.HashMap为什么每次扩容是2的倍数?
https://blog.csdn.net/apeopl/article/details/88935422
HashMap计算添加元素的位置时,使用的位运算,这是特别高效的运算;另外,HashMap的初始容量是2的n次幂,扩容也是2倍的形式进行扩容,是因为容量是2的n次幂,可以使得添加的元素均匀分布在HashMap中的数组上,减少hash碰撞,避免形成链表的结构,使得查询效率降低
5.当HashMap中链表过长为什么使用红黑树?
PS:
HashMap 是数组 + 单向链表 + 红黑树 ,其中单向链表是存储在尾部的,无论是存头还是存尾部,都需要把整个链表遍历一遍。因为存在hash碰撞的时候需要判断equals是否也相同。如果相同并不会存储 而是替换。