前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Hashmap1.7和1.8区别

Hashmap1.7和1.8区别

作者头像
终有救赎
发布2023-10-16 10:22:13
3650
发布2023-10-16 10:22:13
举报
文章被收录于专栏:多线程

Hashmap1.7和1.8 主要有四个区别,下面将一一说明

存储结构

在1.7版本中,HashMap使用数组+链表的方式实现,即当发生哈希冲突时,会使用链表将冲突的元素串起来。 在1.8版本中,当链表长度超过一定阈值(默认为8)时,链表会转化为红黑树,以提高查找效率。

并发性

在1.7版本中,HashMap在多线程环境下存在并发问题,可能导致死循环。 在1.8版本中,HashMap引入了"锁分段"机制,将整个存储空间分成了多个段(默认为16段),每个段独立加锁,可以提高并发性能。

扩容机制

在1.7版本中,HashMap的扩容机制是当元素个数超过容量的75%时进行扩容,扩容后容量会翻倍,把所有元素重新计算一遍位置,为了降低hash冲突。 在1.8版本中,扩容机制进行了优化,当链表长度超过一定阈值(默认为8)且元素个数超过容量的75%时,会进行链表转换为红黑树的操作,并且扩容时不再翻倍,而是以原来容量的两倍进行扩容,扩容后,不会把所有元素重新计算一遍位置。

在这里插入图片描述
在这里插入图片描述

PUT插入方式

JDK1.7用的是头插法,而JDK1.8及之后使用的都是尾插法,因为JDK1.7是用单链表进行的纵向延伸,当采用头插法时会容易出现逆序且环形链表死循环问题。但是在JDK1.8之后是因为加入了红黑树使用尾插法,能够避免出现逆序且链表死循环的问题。

相关问题

  1. 为什么在JDK1.7的时候是先进行扩容后进行插入,而在JDK1.8的时候则是先插入后进行扩容的呢? ​ 其实就是当这个Map中实际插入的键值对的值的大小如果大于这个默认的阈值的时候(初始是16*0.75=12)的时候才会触发扩容
  2. 为什么在JDK1.8中进行对HashMap优化的时候,把链表转化为红黑树的阈值是8,而不是7或者不是20呢? ​ 如果选择6和8(如果链表小于等于6树还原转为链表,大于等于8转为树),中间有个差值7可以有效防止链表和树频繁转换。假设一下,如果设计成链表个数超过8则链表转换成树结构,链表个数小于8则树结构转换成链表,如果一个HashMap不停的插入、删除元素,链表个数在8左右徘徊,就会频繁的发生树转链表、链表转树,效率会很低。 ​ 还有一点重要的就是由于treenodes的大小大约是常规节点的两倍,因此我们仅在容器包含足够的节点以保证使用时才使用它们,当它们变得太小(由于移除或调整大小)时,它们会被转换回普通的node节点,容器中节点分布在hash桶中的频率遵循泊松分布,桶的长度超过8的概率非常非常小。所以作者应该是根据概率统计而选择了8作为阀值
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-10-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 存储结构
  • 并发性
  • 扩容机制
  • PUT插入方式
  • 相关问题
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档