From 7f9ba7ec6c43af2f9e448558410028530ff07ef7 Mon Sep 17 00:00:00 2001 From: guide Date: Thu, 25 Feb 2021 15:34:09 +0800 Subject: [PATCH] =?UTF-8?q?Update=20HashMap(JDK1.8)=E6=BA=90=E7=A0=81+?= =?UTF-8?q?=E5=BA=95=E5=B1=82=E6=95=B0=E6=8D=AE=E7=BB=93=E6=9E=84=E5=88=86?= =?UTF-8?q?=E6=9E=90.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...Map(JDK1.8)源码+底层数据结构分析.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/java/collection/HashMap(JDK1.8)源码+底层数据结构分析.md b/docs/java/collection/HashMap(JDK1.8)源码+底层数据结构分析.md index 03ad0e3e..977fdf78 100644 --- a/docs/java/collection/HashMap(JDK1.8)源码+底层数据结构分析.md +++ b/docs/java/collection/HashMap(JDK1.8)源码+底层数据结构分析.md @@ -77,7 +77,7 @@ static int hash(int h) { 相比于之前的版本,JDK1.8 以后在解决哈希冲突时有了较大的变化。 -当链表长度大于阈值(默认为 8)时,会首先调用 `treeifyBin()`方法,这个方法会根据 HashMap 数组来决定是否转换为红黑树。只有当数组长度大于或者等于 64 的情况下,才会执行转换红黑树操作,以减少搜索时间。否则,就是只是执行 `resize()` 方法对数组扩容。相关源码这里就不贴了,重点关注 `treeifyBin()`方法即可! +当链表长度大于阈值(默认为 8)时,会首先调用 `treeifyBin()`方法。这个方法会根据 HashMap 数组来决定是否转换为红黑树。只有当数组长度大于或者等于 64 的情况下,才会执行转换红黑树操作,以减少搜索时间。否则,就是只是执行 `resize()` 方法对数组扩容。相关源码这里就不贴了,重点关注 `treeifyBin()`方法即可! ![](https://oscimg.oschina.net/oscnet/up-bba283228693dae74e78da1ef7a9a04c684.png) @@ -265,13 +265,13 @@ HashMap 只提供了 put 用于添加元素,putVal 方法只是给 put 方法 1. 如果定位到的数组位置没有元素 就直接插入。 2. 如果定位到的数组位置有元素就和要插入的 key 比较,如果 key 相同就直接覆盖,如果 key 不相同,就判断 p 是否是一个树节点,如果是就调用`e = ((TreeNode)p).putTreeVal(this, tab, hash, key, value)`将元素添加进入。如果不是就遍历链表插入(插入的是链表尾部)。 -说明:下图有两个小问题: - -- [issue#608](https://github.com/Snailclimb/JavaGuide/issues/608)指出:直接覆盖之后应该就会 return,不会有后续操作。参考 JDK8 HashMap.java 658 行。 -- 当链表长度大于阈值(默认为 8)并且 HashMap 数组长度超过 64 的时候才会执行链表转红黑树的操作,否则就只是对数组扩容。参考 HashMap 的 `treeifyBin()` 方法 - ![ ](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/put方法.png) +说明:上图有两个小问题: + +- 直接覆盖之后应该就会 return,不会有后续操作。参考 JDK8 HashMap.java 658 行([issue#608](https://github.com/Snailclimb/JavaGuide/issues/608))。 +- 当链表长度大于阈值(默认为 8)并且 HashMap 数组长度超过 64 的时候才会执行链表转红黑树的操作,否则就只是对数组扩容。参考 HashMap 的 `treeifyBin()` 方法([issue#1087](https://github.com/Snailclimb/JavaGuide/issues/1087))。 + ```java public V put(K key, V value) { return putVal(hash(key), key, value, false, true); @@ -306,7 +306,9 @@ final V putVal(int hash, K key, V value, boolean onlyIfAbsent, if ((e = p.next) == null) { // 在尾部插入新结点 p.next = newNode(hash, key, value, null); - // 结点数量达到阈值,转化为红黑树 + // 结点数量达到阈值(默认为 8 ),执行 treeifyBin 方法 + // 这个方法会根据 HashMap 数组来决定是否转换为红黑树。 + // 只有当数组长度大于或者等于 64 的情况下,才会执行转换红黑树操作,以减少搜索时间。否则,就是只是对数组扩容。 if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st treeifyBin(tab, hash); // 跳出循环