HashMap常见面试题分析
HashMap常见面试题分析
1、HashMap底层是如何实现的?
首先底层数据结构是由数组+链表组成链表散列。HashMap先得到key的散列值,在通过扰动函数(减少碰撞次数)得到Hash值,接着通过hash & (n -1 ),n位table的长度,运算后得到数组的索引值。如果当前节点存在元素,则通过比较hash值和key值是否相等,相等则替换,不相等则通过拉链法查找元素,直到找到相等或者下个节点为null时。
1.8对扰动函数,扩容方法进行优化,并且增加了红黑树的数据结构。
2、HashMap 和 Hashtable 的区别
1.线程安全: HashMap是线程不安全的,而HashTable是线程安全的,每个人方法通过修饰synchronized来控制线程安全。
2.效率: HashMap比HashTable效率高,原因在于HashTable的方法通过synchronized修饰后,并发的效率会降低。
3.允不允许null: HashMap运行只有一个key为null,可以有多个null的value。而HashTable不允许key,value为null。
3、HashMap1.7和HashMap1.8有什么区别:
1.7 底层用的是数组+链表实现的
1.8 底层用的是数组+链表+转换红黑树实现的
4、HashMap的put方法底层是如何实现:
1、判断key如果为空的情况下,存放数组0
2、默认HashMap初始容量为16、负载因子大小 160.75 = 12 , 每次扩容 2 倍
3、根绝key计算hash值,存放到数组下标等于hash值的位置
4、如果计算出的hash值的位置已经存在数据(hash冲突),但是内容不等,则通过链表进行存储
5、如果当前size > 负载因子阈值,开始2扩容
备注:1.8 中链表长度如果大于8的情况下,开始将链表转换为红黑树
5、1.8的HashMap解决了1.7中的什么问题
1、1.8采用的是尾插入法
2、解决了1.7HashMap死循环的问题
3、链表长度>8转换为红黑树
6、HashMap线程不安全,高并发的时候用什么呢?
ConcurrentHashMap 、或者使用Collecitons.synchronizedMap(map)
为什么不用HashTable呢?
因为HashTable用的是Synchronized锁,在高并发的情况下,很多线程去竞争一个锁,导致效率非常低下!
为什么用ConcurrentHashMap呢?
1.7中: ConcurrentHashMap 内部是通过 继承ReentrantLock 的内部类(Segment类)来实现线程安全的 ,而且 里边的节点(Entry)也通过 volatile 修饰保证它的内存可见性。
1.8中:它不再使用上述的Segment类,而是通过 cas + synchronized 保证并发安全。
7、HashMap的长度为什么是2的幂?
在HashMap的操作流程中,首先会对key进行hash算法得到哈希值,其次哈希值会与哈希数组长度取余得到一个索引值,即 h = hash % n (n为哈希数组的长度),这个索引值h就是对应哈希桶数组的索引。又因为&比%运算快,假设n是2的幂,可以用&运算替换%运算,公式会变成 hash & (n-1)。所以这就解释了为什么HashMap长度是2的幂。