源码硬讲HashMap结构及数据结构转换过程(图+文)

1 缘起

补充树相关的知识过程中,学习到红黑树,并查了一些红黑树的应用,
发现Java提供的数据工具包:HashMap中使用了红黑树,
之前在应对知识考核时也看了HashMap的相关数据组成,
但是,没有详细分析数据之间是如何转换存储结构的,
现在,正好借着学习树以及应用的机会,根据HashMap源码,
详细研究了HashMap的数据转换过程,
分享如下,
帮助读者轻松应对知识考核与交流。

2 分析

2.1 理论:回顾HashMap

HashMap是一个组合的数据结构。
根据自己动手丰衣足食的设计原则,当某种开发语言不支持更加高效的数据结构存储数据时,
开发者可根据实际需要,编写自己的数据结构,
这不,Java工具包开发者组合了数组、链表和红黑树,创造了HashMap,
集相对高效的CURD于一身。
老规矩,根据理论,
先看看HashMap的数据结构,如下图所示,
由图可知,HashMap默认的数组元素有16个,
数组中的元素存储情况:
(1)key没有Hash冲突,则按照kv形式存储,如key2对应的形式;
(2)key有Hash冲突且冲突的key个数小于7个,使用链表存储,如key1对应的形式;
(3)key有Hash冲突且冲突的key个数大于等于7个,使用红黑树存储,如key3对应的形式。

在这里插入图片描述

2.2 实践:新增数据

使用HashMap存储数据,暴露给用户的方法为put,源码如下图所示,
由源码可知,put方法中,调用了putVal方法,这个方法才是实际的存储数据和数据结构转换的方法。
位置:java.util.HashMap#put
在这里插入图片描述

既然putVal才是最终的奥义,
那么继续看看这个方法的真实面目,如下图所示,
新增数据,
我已经将数据的类型和数据结构的变化在图中标出,
各位习者耐心看下,设计非常巧妙,
Node<>[]即数组;
p.next即链表,
treeifyBin即红黑树。

位置:java.util.HashMap#putVal
在这里插入图片描述

2.3 Node

HashMap的Node有两种功能,
(1)直接存储kv;
(2)转换为单向链表;
源码如下图所示,有源码可知,属性key、value即可直接存储kv;
属性next即单向链表结构,使用链表存储数据。
在这里插入图片描述

2.4 TreeNode

前面的Node用于存储kv或者单向链表,
那么,红黑树则使用TreeNode存储数据,
属性,parent连接父节点,left和right是该节点的左右节点,prev前驱节点,删除时断开与next的连接,
red用于标识当前节点的特性:红或黑。
位置:java.util.HashMap.TreeNode
在这里插入图片描述

2.5 树化:构建红黑树

树化的方法为treeifyBin,即构建树化容器,
源码如下图所示,
有源码可知,首先构建TreeNode,然后通过treeify构建红黑树,
是的,核心是treeify方法。
位置:java.util.HashMap#treeifyBin
在这里插入图片描述
构建红黑树:
源码如下图所示。
位置:java.util.HashMap.TreeNode#treeify
在这里插入图片描述

3 小结

(1)HashMap由3种数据结构构成:数组、单向链表和红黑树;
(2)数据结构转换过程:
(2.1)key没有Hash冲突,则按照kv形式存储,如key2对应的形式;
(2.2)key有Hash冲突且冲突的key个数小于7个,使用链表存储,如key1对应的形式;
(2.3)key有Hash冲突且冲突的key个数大于等于7个,使用红黑树存储,如key3对应的形式。
(3)红黑树转换时,先构建TreeNode数组,然后转换为红黑树,红黑树转换的核心方法为:java.util.HashMap.TreeNode#treeify。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天然玩家

坚持才能做到极致

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值