编辑
2023-11-11
面试题库
0
请注意,本文编写于 438 天前,最后修改于 244 天前,其中某些信息可能已经过时。

在Java中,HashMap是一种用于存储Key-Value键值对的数据结构,它在内存中的存储实际上是一个数组结构,数组的每一项称为一个桶,每一个桶中可以存放一个链表,链表的每一项都包含了一个Key-Value键值对。

正因为此,HashMap能够以常数复杂度(O(1))进行数据的查找和插入操作,但也正因为此,HashMap也存在着“冲突”的问题。

在JDK1.8之前,当冲突发生时,HashMap使用链表来解决冲突,但是在多次冲突的情况下,HashMap的查找性能会降低到O(n),这导致在元素较多时HashMap的效率会大大降低。

而在JDK1.8之后,为了优化多次冲突的情况,HashMap采用了优化后的链表,也就是红黑树,当链表长度大于一定数量(默认为8)时,链表就转为红黑树,这样即使多次冲突,查找性能也可以保持在O(logn)。

JDK1.7 HashMap put流程

在JDK1.7中,HashMap的put流程主要包括以下步骤:

1、计算key的hash值,确定在表中的位置。

2、检查此位置上是否已经存在一个元素,如果不存在,则直接在此位置插入新元素。

3、如果此位置上已经存在一个元素,则遍历该链表,查找是否有与新元素的key相同的旧元素。

4、如果存在与新元素的key相同的旧元素,则替换旧元素的value;如果没有,则将新元素插入到链表的头部。

JDK1.8 HashMap put流程

在JDK1.8中,HashMap的put流程有所改变:

1、和1.7类似,同样首先计算key的hash值,然后确定在表中的位置。

2、如果此位置上不存在元素,则直接在此位置插入新元素。

3、如果此位置上已经存在元素,且key与新元素的key完全相同(即hashCode和equals都相同),则直接替换该元素。

4、如果此位置上的元素形成了链表,那么就遍历该链表,查找是否存在与新元素的Key相同的元素,如果存在则替换value,如果不存在则插入到链表尾部。

5、如果链表长度在此次添加元素后数量达到8,那么就将链表转换为红黑树。

6、如果此位置上的元素形成了红黑树,那么就按照红黑树的方式添加新元素。

在JDK1.8中,不仅改变了元素存在冲突时的存储结构,提高了查找效率,而且还改变了元素添加到链表的方式,从链表头部插入改为链表尾部插入,减少了对链表的中断,提高了HashMap的并发性能。

本文作者:whitebear

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!