使用HashMap优化代码,你得学我这样做
我并没有和HashMap杠上 , 想着重新开始写点技术的东西 , 就拿HashMap开头了 。 最近开始重新学习数据结构和算法 , 其中有些东西学完之后 , 对于HashMap的理解和运用又有新的认识 。 虽然之前运用HashMap也有这样用过 , 但是知道了方法论 , 才发现这样使用的好处 。
上一期我写过HashMap , 写的是JDK8之前的Hash , 现在都JDK15了 , 大家有兴趣可以去看一下源计划之从HashMap认识数据结构
JDK8的HashMap
现在大家基本上使用的JDK版本都是8以上 , 所以JDK8的HashMap更有实用价值 , 那么JDK8之后 , 针对HashMap做了哪些优化呢?
【使用HashMap优化代码,你得学我这样做】hash方法变化:
JDK8之后的Hash算法:
JDK7的hash算法:
可以发现 , JDK8之后使用了三元运算符 , 计算了2次 , 一次右移运算 , 一次异或运算 。
而JDK7中的进行了4次右移运算 , 进行了四次扰动 , JDK在Hash算法上提高了性能 。
存储数据结构的变化:
JDK8之前 , 发生了Hash碰撞之后 , 同一个node节点 , 将存储在链表中 。
本文插图
JDK8之后发生的变化
本文插图
当同一个node节点存储数据大小达到8之后 , 存储结构会将链表变成红黑树 。
那么node节点存储数据大小一开始达到了8 , 后来map数据减少 , 该node数据大小小于8 , node节点的存储结构是否还是红黑树?
答案:node有可能是红黑树 , 也有可能会退化到链表结构 , 因为退化阈值并不是8 , 而是6 。
下面的HashMap源码可以发现 , 当node节点数据大小小于6的时候 , 才会将红黑树转化为链表结构 。
退化阀值为什么会是6 , 而不是8?
答案:虽然在查询效率上 , 链表结构的时间复杂度是O(n)O(n)O(n)红黑树时间复杂度是O(logn)O(logn)O(logn),但是红黑树就是一种特殊的二叉树 , 红黑树在极端的情况下 , 其实是会变成像链表一样 , 数据量小的情况下 , 也最容易发生这种情况 , 在这种情况下 , 红黑树的查询时间复杂度和链表是一样的 , 趋近于O(n),但是红黑树的树节点比普通节点内存大2倍 , 在空间上是不如链表的 , 而以后阀值为6 , 而不和转化为红黑树的阀值一样 , 是为了避免反复转化 。 (这些源码是有参考意义的 , 在我们的业务代码中也可以用这种方式来避免反复的转换)
HashMap扩容时 , 将头插法改为了尾插法:
为什么会出现这种变化呢?在JDK8之前的版本中 , 多线程操作下 , HashMap会出现死循环的问题 , 而这种问题的导致原因就是因为 , HashMap在扩容的时候 , 头插法 , 在链表头部插入 , 导致原有数据的链表位置发生的改变 , 就会出现下面的情况 , 形成环形链表 , 导致死循环 。
- WPS|喜爱大屏手机的用户看过来,这两款大屏手机使用体验堪比平板
- 芯片|一个指令查电脑使用痕迹!动过什么文件,看得清清楚楚
- 搜索引擎|网站优化关键词重点应该做什么?
- 微信|苹果6手机使用了6年,就是微信打开较慢,有解决的办法吗?
- 科学家|科普!二氧化碳培养箱的5条注意事项,直接关系仪器的使用寿命
- 苹果|百度carlife ,华为hicar ,苹果carplay使用感受
- 投影仪|联想t500投影仪怎么样?联想t500和t200区别哪个好?使用评测解读
- 相机|三星Fold 4或将优化相机和屏下表现 Flip 4有望用上新技术
- 索尼相机|你了解图片配置文件吗 它是做什么用的 索尼相机使用介绍
- WPS|WPS最大的败笔是“免费用,广告弹窗”,难怪用户纷纷使用office