库调多了,都忘了最基础的概念 -HashMap 篇

简介: 库调多了,都忘了最基础的概念 -HashMap 篇

🍁 作者:知识浅谈,CSDN博客专家,阿里云签约博主,InfoQ签约博主,华为云云享专家

📌 擅长领域:全栈工程师、爬虫、ACM算法

💒 公众号:知识浅谈

温馨提醒:由于内容较好,请18岁以上成年人观看

🤞这次都给他拿下🤞

🎈说一下HashMap底层实现?及元素添加流程?

因为JDK1.7和JDK1.8是有区别的,所以按照不同的版本记录

JDK1.7版本:

  1. 底层结构使用数组+链表的方式实现。
  2. 数组中最初的大小为16个节点,阈值为0.75,当达到阈值的时候进行扩容,扩容每次扩容为原来的2倍。
  3. 链表插入节点的时候使用头插法。

😉元素添加的过程:这个版本的元素添加是先判断是否达到阈值,即先扩容,后添加。

添加的时候找到对应的位置,如果为空进行赋值,否则如果是链表采用头插法把值插入。

🧐存在的问题:存在循环链表和值覆盖的问题。

JDK1.8版本:

  1. 底层结构使用数组+链表+红黑树的方式实现。
  2. 数组中最初的大小为16个节点,阈值为0.75,当达到阈值的时候进行扩容,扩容每次扩容为原来的2倍,相比于JDK1.7还有一点就是当链表的节点数大于8且整个map中元素的个数大于64的时候,链表转化为红黑树,当链表中的节点数小于6的时候,红黑树退化为链表。
  3. 链表插入节点的时候使用尾插法。

😉元素添加的过程:这个版本的元素添加是先添加,后判断是否进行扩容。

添加的时候找到对应的位置,如果为空进行赋值,否则如果是链表采用尾部插法把值插入,否则如果是红黑树,则在红黑树中插入对应的节点。

🧐存在的问题: 解决了循环链表的问题,但是仍然存在值覆盖的问题。

🎈为什么HashMap会产生死循环?

这个死循环就是上边提到的循环链表的问题,这个问题是发生在扩容的时候,当多个线程进行节点并发插入的时候,都需要进行扩容,一个线程扩容完,另一个线程本来在前一个线程扩容之前已经指向原本的头节点,扩容之后头节点指向的next节点变化了,当第二个线程扩容的时候就行成了循环。

🎈HashMap除了死循环之外,还有什么问题?

正如上边提到的,除了死循环,还有值覆盖的问题,就是当数组中的一个节点为空的时候两个元素要同时插入的时候当一个节点获取了位置要插入的时候,时间片到了,另一个线程插入了,之后到另一个线程的时候也进行了插入,就把之前的给覆盖了。

🎈为什么ConcurrentHashMap是线程安全的?

📐JDK1.7版本:

使用分段锁的形式,即用segment数组来进行加锁的形式,每个锁下记录一个数组+链表的结构,这个数组的初始值和阈值为16和0.75,同理每个segment下都是如此,为什么concurrentHashMap是安全的,就是因为当修改的时候先锁住一个段下的所有内容进行修改,如果不同段中的数据,是可以并行修改的。

📐JDK1.8版本:

采用Synchronized+CMS的形式,就是对数组中每个节点加synchronized的形式,然后在进行扩容,sychronized锁住结点之后使用CMS的方法进行扩容,并且还支持并发扩容,也就是可以多个线程同时进行扩容,且扩容不用计算hash值,如果之前的hash大于原来的数组则就把当前节点移动到当前节点+原数组长度的位置。

🍚总结

以上就是关于hashmap的简单理解,太深了我也不太理解,希望有所帮助。

相关文章
|
存储 Linux 调度
io复用之epoll核心源码剖析
epoll底层实现中有两个关键的数据结构,一个是eventpoll另一个是epitem,其中eventpoll中有两个成员变量分别是rbr和rdlist,前者指向一颗红黑树的根,后者指向双向链表的头。而epitem则是红黑树节点和双向链表节点的综合体,也就是说epitem即可作为树的节点,又可以作为链表的节点,并且epitem中包含着用户注册的事件。当用户调用epoll_create()时,会创建eventpoll对象(包含一个红黑树和一个双链表);
302 0
io复用之epoll核心源码剖析
|
Docker 容器
百度搜索:蓝易云【docker容器/etc/hosts文件修改教程】
现在,你已经成功修改了Docker容器中的 `/etc/hosts`文件,添加了主机名和IP地址的映射关系。这使得在容器内部可以使用指定的主机名来访问相应的IP地址。请确保在修改 `/etc/hosts`文件时小心,避免错误的配置导致意外的问题发生。
436 0
|
存储 SQL 运维
跨节点参数的缘起与今生
Dataphin v3.13引入了跨节点参数功能,允许任务间传递消息。输出节点(如SQL、Shell、Python任务)能输出参数,输入节点可以接收并使用这些参数。此功能解决了通过公共存储中转消息的复杂性和低效问题。应用场景包括:金融企业的币种转换,其中汇率任务(输出节点)提供汇率,转换任务(输入节点)使用该汇率;以及产品目录更新检查,通过跨节点参数控制是否需要执行数据导入任务。用户可以通过任务编辑器设置和传递跨节点参数,并在运维中进行补数据操作。
511 2
跨节点参数的缘起与今生
|
机器学习/深度学习 人工智能 自然语言处理
大模型是如何理解人类语言的?
大模型是如何理解人类语言的?
632 0
|
监控 安全 BI
阿里云国际跨账号迁移CDN域名操作步骤
阿里云国际跨账号迁移CDN域名操作步骤
|
消息中间件 存储 缓存
深入理解Kafka核心设计及原理(五):消息存储
深入理解Kafka核心设计及原理(五):消息存储
411 8
|
JavaScript 前端开发
vue 页面下滚到目标元素的位置,目标元素自动吸顶(自动悬浮吸附到页面顶部)
vue 页面下滚到目标元素的位置,目标元素自动吸顶(自动悬浮吸附到页面顶部)
695 0
|
人工智能 数据处理 Python
🔍数据侦探的AI助手:Prompt技巧大公开,洞察商业先机不手软
【8月更文挑战第1天】在数据驱动时代,AI助手作为数据侦探的强大伙伴,通过精心设计的AI Prompt技巧帮助解析复杂市场。案例中,一电商平台欲进入新兴市场,面临数据挑战。初始Prompt聚焦消费者偏好及影响因素分析。为进一步深化洞察,Prompt加入节假日购物模式、商品类别偏好及社交媒体影响等细节。结合领域知识,优化Prompt关注价格敏感度与定制化营销策略。最终,AI助手生成的报告揭示了消费者行为模式,并提出市场策略建议,助力电商成功布局新兴市场。此过程展示了AI Prompt在商业洞察中的关键作用,预示着其在未来洞察之旅中的广阔前景。
515 2
|
消息中间件 存储 Java
【RocketMQ系列一】初识RocketMQ
【RocketMQ系列一】初识RocketMQ
287 1
|
PHP
明星百科大全PHP网站源码
明星百科大全网站源码,国内外明星娱乐音乐、新闻八卦、写真照片、相关影视作品等等的明星百科网站源码。
397 4