最近在找工作的时候常被问道的就是“你知道HashMap的底层原理吗?”
这个问题被问的几率很高,所以记录一下。
那么说到HashMap就不得不说HashMap的版本了,HashMap可以分为两个版本那就是1.7和1.8,在1.7的时候采用的是桶加链的方式进行存储数据,而在1.8之后采用数组+链表+红黑树的方式进行存储,且1.7在存储的时候会采用的是头插法,这个头插法呢就是将数据每次都差在链表的头结点上,每次插入都会改变原有元素的顺序,在并发的情况下会导致链表成环的问题,1.8之后采用尾插法在添加数据时不会改变原有数据的顺序,所以就避免了链表成环的问题。我先现在使用的就是1.8的HashMap。
1.8版的HashMap有几个重要的数据,如初始容量16,负载因子0.75,数组最大容量64,链表最大深度8,红黑树的最小深度6等几个重要数据。
首先来说说初始容量16,在源码中会有这样的一条语句,如下:
它说的就是数组的初始长度为16,使用hash来计算数据要存入的位置,
第二个重要的数据就是负载因子0.75,源码为:
它说的是当在数组中的数据存储量达到当前容量的0.75的时候,数组就需要扩容,也就是说在数组容量为16时,数组中的数据容量达到了12 ,此时就要进行扩容,扩容到32,也就是再次左移一位,进行扩容,第三个重要数据是数组最大长度64,源码如下:
就是说数组的最大长度只能扩容到64,那么数据是如何在map中存储呢,我们都知道map是按key-value的方式进行存储,那么在底层存储的时候会根据它的key进行hash计算,得到它在数组中存放的位置,如果该位置已存在数据,那么就会发生hash冲突,这时就会在数组的改位置下生成一个链表,放在原有数据之下,那么这时就使用到了第四个重要数据,链表深度8,源码如下:
它的意思就是说链表的最大深度为8 ,如果超过8它的存取速度就不会是最优的,它会将该链表甩成一个树来存储,当以树的结构来存储的时候就处在了第五个重要的数据树的最小深度来规范,源码如下:
它的作用是当树的深度小于6的时候,就会将树重新排列成链表,这样的效果是最优的存取方式。
这就是我对HashMap的一个浅显的理解了,如果错误之处,望指出,谢谢。