一、jdk1.7中HashMap的底层实现原理
首先,当我们通过HashMap的构造方法创建一个HashMap对象时,底层就会创建一个Entry类型的一维数组(默认初始化长度为16)。当我们执行put操作的时候,会调用key所属类的hashCode方法计算出key的hash值,然后将hash值通过哈希函数计算出更加复杂的hash值,再将算出的hash值和数组长度进行&运算(位运算的一种),获得当前put进来的数据要在Entry数组中存放的位置。然后就去数组上找这个位置,此时有两种情况:
一是该数组位置上是空的,此时直接将put进来的键值对存放在数组的该位置上。
二是该数组位置上不为空(说明此位置上已经存放了一个或多个元素,通过链表的方式),已经有元素了(这种现象称为哈希冲突,即哈希函数算出来的地址被别的元素占用了)。此时就需要将put进来的key的哈希值和该位置上存放的所有元素的key的哈希值逐一进行比较。这里又有两种情况:
1.哈希值都不同:此时就可以认为put进来的键值对是一个新的元素,继续以链表的形式存储。
2.哈希值相同:注意,哈希值相同并不能就确定他们是相同的对象,还需要调用他们的key中的equals方法进一步进行比较,这里又有两种情况
a.两个key进行equals后返回true,则证明这两个key是相同的。map不允许存储相同的key,于是会把原来的value,替换为put进来的value值。
b.两个key进行equals后返回false,则证明这两个key是不同的,继续以链表的形式存储put进来的键值对。
二、jdk1.8中HashMap的底层实现原理
jdk1.8中HashMap的底层实现与jdk1.7基本一样,但是有少许变化,下边只讲变化的地方。
1.jdk7中,键值对会被封装为entry对象,而jdk8是封装为Node对象。
2.jdk7中 数组在调用Hashmap的构造方法时创建,而jdk8中数组创建是在第一次调用put方法。
3.jdk7底层结构只有:数组+链表。jk8中底层结构:数组+链表+红黑树
拓展:红黑树什么时候被使用?
当数组的某一个索引位置上的元素以链表形式存在的数据个数>8且当前数组的长度>64时,此时此素引位置上的所有数据改为使用红黑树存储