HashMap添加元素的过程(重点详解)

  • Post author:
  • Post category:其他


以jdk7为例说明:

HashMap map = new HashMap();

在实例化以后,底层创建了一个长度为16的一位数组Entry[] table。

···可能已经执行过多次put操作了···

map.put(key1,value1)

首先会调用key1所在类的hashCode()方法计算key1的哈希值,然后通过某种算法计算出key1在Entry数组中的存放位置。

如果此位置上没有存放数据,则(key1-value1)添加成功。

如果此位置上有数据,则比较key1和已经存放的数据(一个或多个数据,其中多个数据是以链表的形式存储)的哈希值

如果key1的哈希值和已经存放的数据的哈希值都不相同,则(key1-value1)添加成功。

如果key1的哈希值和已经存放的某一个数据(key2-value2)的哈希值相同,则调用key1所在类的equals(key2)方法

如果equals返回false,则(key1-value1)添加成功。

如果equals返回true,则使用value1替换value2。

在不断添加的过程中:会涉及到扩容问题,当超出临界值时且要存放的位置非空时,默认情况下,扩容为原来的2倍,并把原来的数据复制过来。

jdk8中:

new HashMap():底层没有创建一个长度为16的数组。

jdk8底层的数组是:Node[],而非Entry数组。

首次调用put()方法时,底层去创建长度为16的数组。

jdk7底层结构:数组+链表。

jdk8底层结构:数组+链表+红黑树。

当数组的某一个索引位置上的元素以链表形式存在的数据个数>8且当前数组的长度>64时,此时此索引位置上的所有数据由数组+链表改为使用数组+红黑树存储,当数组的某一个索引位置上的元素以红黑树形式存在的数据个数<6时,此时此索引位置上的所有数据由数组+红黑树变为使用数组+链表存储。



版权声明:本文为qq_55991094原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。