HashMap略解

Java面试突击
1.HashMap略解


前言

日常工作开发中,我们经常会使用HashMap这种数据结构,进行一定的逻辑处理,很多时候我们只是会使用,而不知其所以然

一、HashMap底层数据结构

用一个示例来说明:
我们创建一个一个map集合

HashMap<String,String> map = new HashMap<String,String>(); 
map.put("Hash1","Map1");
map.put("Hash2","Map2");

实际上的底层存储逻辑类似下面这样:

[<>,<>,<Hash1,Map1>,<Hash2,Map2>,......]

所以我们可以看到,HashMap的底层数据结构是数组

但是当我们对某一元素进行取模时,可能会存在两个不同的Key返回相同的hashCode,此时,会将这个数据放在数组的同一位置处,这将会使其变为一个链表结构的数据。

二、1.7升级1.8之后对比

1.JDK7 HashMap如何实现

链接:https://www.pdai.tech/md/interview/x-interview.html

哈希表有两种实现方式,一种开放地址方式(Open addressing),另一种是冲突链表方式(Separate chaining with linked lists)。Java7 HashMap采用的是冲突链表方式。

2.JDK8 HashMap如何实现

根据 Java7 HashMap 的介绍,我们知道,查找的时候,根据 hash 值我们能够快速定位到数组的具体下标,但是之后的话,需要顺着链表一个个比较下去才能找到我们需要的,时间复杂度取决于链表的长度,为 O(n)。 为了降低这部分的开销,在 Java8 中,当链表中的元素达到了 8 个时,会将链表转换为红黑树,在这些位置进行查找的时候可以降低时间复杂度为 O(logN)。

简而言之:1.7基于哈希表实现,1.8基于数组+链表+红黑树

三、HashMap扩容

结合HashMap底层数据结构,当这个数组满了之后,他就会自动进行扩容,编程一个更大的数组,一般来说是进行2倍扩容
在扩容时,对原有数据会进行rehash,对所有的数组数据重新判断二进制结果是否多出一个bit的1,如果没有,那么就是原来的index,如果多了出来,那么就是index+oldCap,并不是粗鲁的在原来的数组后面继续添加1倍的长度。

总结

本文仅仅简单介绍了HashMap的一般考察点,至于详细的rehash,请查阅官方资料。

猜你喜欢

转载自blog.csdn.net/PhilipJ0303/article/details/124973868