声明:本文以jdk1.8为主!
搞定HashMap
作为一个Java从业者,面试的时候肯定会被问到过HashMap,因为对于HashMap来说,可以说是Java==集合中的精髓==了,如果你觉得自己对它掌握的还不够好,我想今天这篇文章会非常适合你,至少,看了今天这篇文章,以后不怕面试被问HashMap了
其实在我学习HashMap的过程中,我个人觉得HashMap还是挺复杂的,如果真的想把它搞得明明白白的,没有足够的内力怕是一时半会儿做不到,不过我们总归是在不断的学习,因此真的不必强迫自己把现在遇到的一些知识点全部搞懂。
但是,对于HashMap来说,你所掌握的应该足够可以让你应对面试,所以今天咱们的侧重点就是学会那些经常被问到的知识点。
我猜,你肯定看过不少分析HashMap的文章了,那么你掌握多少了呢?从一个问题开始吧
新的节点在插入链表的时候,是怎么插入的?
怎么样,想要回答这个问题,还是需要你对HashMap有个比较深入的了解的,如果仅仅知道什么key和value的话,那么回答这个问题就比较难了。
这个问题大家可以先想想,后面我会给出解答,下面我们一步步的来看HashMap中几个你必须知道的知识点。
Map是个啥?
HashMap隶属于Java中集合这一块,我们知道集合这块有list,set和map,这里的HashMap就是Map的实现类,那么在Map这个大家族中还有哪些重要角色呢?
![37f665fa5a7da691efa422699e2b260e.png](https://i-blog.csdnimg.cn/blog_migrate/f4ad8ae55ade0c7a108472845eb53dc1.jpeg)
上图展示了Map的家族,都是狠角色啊,我们对这些其实都要了解并掌握,这里简单的介绍下这几个狠角色:
TreeMap从名字上就能看出来是与树有关,它是基于树的实现,而HashMap,HashTable和ConcurrentHashMap都是基于hash表的实现,另外这里的HashTable和HashMap在代码实现上,基本上是一样的,还记得之前在讲解ArrayList的时候提到过和Vector的区别嘛?这里他们是很相似的,一般都不怎么用HashTable,会用ConcurrentHashMap来代替,这个也需要好好研究,它比HashTable性能更好,它的锁粒度更小。
由于这不是本文的重点,只做简单说明,后续会发文单独介绍。
简单来说,Map就是一个映射关系的数据集合,就是我们常见的k-v的形式,一个key对应一个value,大致有这样的图示
![9978f5122005de89812300c33ea1a907.png](https://i-blog.csdnimg.cn/blog_migrate/1636670d1c328a64baf7f9363eef355f.jpeg)
这只是简单的概念,放到具体的实例当中,比如在HashMap中就会衍生出很多其他的问题,那么HashMap又是个啥?
HashMap是个啥
上面简单提到过,HashMap是基于Hash表的实现,因此,了解了什么是Hash表,那对学习HashMap是相当重要。
建议了解了哈希表之后再学习HashMap,这样很多难懂的也就不那么难理解了。
接着,HashMap是基于hash表的实现,而说到底,它也是用来存储数据供我们使用的,那么底层是用什么来存储数据的呢?可能有人猜到了,还是数组,为啥还是数组?想想之前的ArrayList。
所以,对于HashMap来说,底层也是基于数组实现,只不过这个数组可能和你印象中的数组有些许不同,我们平常整个数组出来,里面会放一些数据,比如基础数据类型或者引用数据类型,数组中的每个元素我们没啥特殊的叫法。
但是在HashMap中人家就有了新名字,我发现这个知识点其实很多人都不太清楚:
在HashMap中的底层数组中,每个元素在jdk1.7及之前叫做Entry,而在jdk1.8之后人家又改名叫做Node。
这里可能还是会有人好奇这Entry和Node长啥样,这个看看源码就比较清楚了,后面我们会说。
到了这里你因该就能简单的理解啥是HashMap了,如果你看过什么是哈希表了,你就会清楚,在HashMap中同样会出现哈希表所描述的那些问题,比如:
- 如何确定添加的元素在底层数组的哪个位置?
- 怎么扩容?
- 出现冲突了怎么处理?
- 。。。
没事,这些问题我们后续都会谈到。
HashMap初始化大小是多少
先来看HashMap的基础用法:
HashMap map = new HashMap();复制代码
就这样,我们创建好了一个HashMap,接下来我们看看new之后发生了什么,看看这个无参构造函数吧
public HashMap() { this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted }
解释下新面孔:
- loadFactor : 负载因子,之前聊哈希表的时候说过这个概念
- DEFAULT_LOAD_FACTOR : 默认负载因子,看源码知道是0.75
很简单,当你新建一个HashMap的时候,人家就是简单的去初始化一个负载因子&