2.1、HashMap的底层实现原理?
以jdk7为例说明:
-
HashMap map = new HashMap();
-
在实例化以后,底层创建了长度是16的一位数组Entry table
-
map.put(key1,value1);
-
首先调用key1所在类的==hashCode()==计算key1哈希值,此哈希值经过某种算法计算以后,得到在Entry数组中的存放位置。如果此存放位置的数据为空,此时的key1-value1添加成功。---------情况1
-
如果此存放位置上的数据不为空,(意味着此位置上存在着一个或者多个数据(以链表形式存在)),比较当前的key1和已经存在的一个或者多个数据的哈希值
-
如果key1的哈希值与已经存在的数值哈希值都不相同,此时添加成功—情况二
-
如果key1的哈希值与已经存在的数据(key2-value2)哈希值都相同,继续比较:调用key1所在类的equals()方法,比较
- 如果equals()返回false,此时key1-value1添加成功----情况3
- 如果equals()返回true,使用value去替换相同key的value值
-
补充:情况2和情况3,此时key1-value1和原来的数据以链表的方式存储
不断的添加过程中,会涉及扩容问题:默认扩容方式:扩容为原来容量的2倍,并将原有的数据复制过来
jdk8相比较于jdk7在底层实现方面的不同:
- new HashMap():底层没有创建一个长度为16的数组
- jdk 8底层的数组是 Node[ ],而非Entry[ ]
- 首次调用put方法时,底层创建长度为16 的数组
- jdk7底层结构只有:数组+链表。jdk8中底层结构:数组+链表+红黑树
- 当数组的某一个索引位置上的元素以链表形式存在的数据个数>8且当前数据的长度>64,此时此索引位置上的所有数据改为红黑树存储