文章目录
1、什么是HashMap
和 JDK7 版本的 HashMap 结构大体一致,多了红黑树。

如果还没看过的或者忘记了的可以先去回顾下,这样可以更好的了解 JDK8 下的 HashMap 基于 JDK7 做了什么改动。分析 JDK8 下的 HashMap 主要是因为 JDK8 在目前使用已成主流,且其在某些性能程度远远大于 JDK7。下面逐一分析。
2、构造函数




和 JDK7 一样,有两个参数:loadFactor和Capacity,分别为负载因子和容量。
如果没有设定,会有默认值:


和 JDK7 一样,我们依旧没有在构造函数中看到 table 的创建,它还是在put中进行创建。
3、table 的创建
当我们对一个 HashMap 第一次put操作时,会开始创建 table:

要研究 table ,得知道它的类型和容量。我们进入resize()方法:

可以看到,代码量比较多,我们不一行一行来分析,我们只根据主要的来分析来龙去脉。首先知道,它返回一个newTab,找到这个newTab的赋值部分:

可见,newTab是一个Node[]类型的数组,因为这里是第一次创建,oldTab就是为 null。
JDK7 的 table 是Entry[]类型的数组,这个Node我们看一下定义:

和 JDK7 的Entry对比一下:

区别就在于,JDK8 给 key 也加了 final 关键字,猜测是为了防止键值对的键被修改导致和哈希值对应不上。其他的和 Entry 没多大区别。从下面开始就把键值对称为 Node,而不是 Entry。
继续分析 table 的创建,上面已经知道 table 的每一个元素都是一个 Node,且 table 的容量为 newCap,继续追踪这个newCap的来源:

第一次创建 table 时,没有所谓的旧 table,所以oldCap和oldThr为0。可以看到容量和阈值都有初始值:DEFAULT_INITIAL_CAPACITY和DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY,查看他们的定义:


本文详细解析了HashMap的工作原理,包括构造函数、table创建、Put和Get操作、扩容机制、并发线程安全问题,以及JDK7与JDK8的差异。
最低0.47元/天 解锁文章
657

被折叠的 条评论
为什么被折叠?



