一文搞懂HashMap1.7、HashMap1.8的底层是如何实现的

        首先,在研究HashMap的底层实现原理之前,我们先来看看equals和hashcode,hash碰撞这些问题。

疑问1:equals和 == 的区别?     

        (1)equals比较的时候,如果是引用类型(除了String类型),那么使用的是object中的equals方法,比较的是地址是否一样;

        如果是String类型的对象,那么String类重写了Object中的equals方法,首先比较地址是否一样,一样的话返回true,不一样再比较是否是为同种类型,不是同类型就返回false,同类型之后再看内容是否一样;内容一样返回true,不一样返回false。

        如果是基本数据类型对应的包装类,使用的equals也不是Object中的equals方法,而是重写了这个方法,首先比较的是否是同类型,不是同类型,直接返回false,是同类型再比较内容是否一致,一致返回true。

        (2)==比较的是地址,引用类型(除了String类型)的时候,只要不是同一个对象那么不是一个地址,String类型的时候如果new出来两个对象,那么也是不同地址,如果不new,那么就是同一个地址,因为都是存放在字符串常量池中,如果是基本数据类型,都是放在常量池中,所以地址都是一样的。

疑问2:为什么重写equals还要重写hashcode?

Hashcode相等,内容不一定相等,但内容相等,hashcode一定相等。

定律:

如果两个对象的hashcode值相等的情况下,对象的内容值不一定相等(会发生hash碰撞的问题)

如果使用equals方法去比较两个对象内容值,相等的情况下,则两个对象的hashcode相同。

        将对象放入到集合中时,首先判断要放入对象的hashcode值与集合中的任意一个元素的hashcode值是否相等,如果不相等直接将该对象放入集合中。如果hashcode值相等,然后再通过equals()判断要放入对象与该存储区域的任意一个对象是否相等,如果equals()判断不相等,直接将该元素放入到集合中,否则不放入。

同样,在使用get()查询元素的时候,集合类也先调key.hashCode()算出数组下标,然后看equals()的结果,如果是true就是找到了,否则就是没找到。

疑问3:如何理解hashcode碰撞问题?

定义对象作为key的时候,一定要重写equals方法和hashcode方法,保证对象key不重复创建。

1、hashmap和hashtable的区别

         hashmap线程不安全,允许存放key为空,放在数组下标为0的位置。

         hashtable线程安全,不允许存放key为空,底层原理:先获取synchronize锁,如果下标一样,则覆盖。

2、hashmap底层如何降低hash冲突概率

        通过二进制去计算hashcode,这样就可以保证均匀存放每个下标的位置,可以直接根据下标位置定位到该元素,这样时间复杂度就是O(1)。

3、hashmap的底层实现原理

(1)基于arraylist集合方式实现

优点:不需要考虑hash碰撞问题,因为它是从头查到尾。

缺点:效率比较低,从头查到尾,时间复杂度为o(n)。

(2)基于数组 + 链表方式(jdk1.7)

hashmap中key如果没有发生碰撞问题,get查询时间复杂度为O(1).

数组初始容量(默认是16),在0.75*16=12的时候进行扩容,之后扩容会按照1.5倍进行扩容,

比如存第17个数据时,数组长度变为16*1.5=24,

存第25个数据的时候,数组长度变为24*1.5=36

(3)基于数组 + 链表 + 红黑树(jdk1.8)

当数组容量 > 64 链表长度 > 8 时,转换成红黑树进行存储,

当红黑树节点个数小于6时,转换成链表进行存储。

4、hashmap1.7 和 hashmap1.8的区别

(1)hashmap1.7是基于数组 + 链表实现的(时间复杂度为O(n)),

        hashmap1.8是基于数组 + 链表 + 红黑树实现的(时间复杂度为O(LogN))。

(2)hashmap1.7在进行扩容的时候,把老的链表存放到新的table中时,采用的是头插入法,源码的写法比较简单,在多线程的情况下,会造成死循环的现象。

hashmap1.8在进行扩容的时候,采用尾插法,写法比较高大上,使用"与运算",产生高位链表和低位链表,最终将两个链表放入到table中,将链表长度缩短,能够降低key对应的index发生冲突,能够提高链表的查询效率。

5、concurentHashmap的底层实现原理

1.7实现原理:

        将一个大的ConcurrentHashmap集合拆分成n多个不同的小的hashtable(16个,Segment(底层采用lock锁),在每个小的hashtable中都有自己独立的table数组,每次扩容的时候只会扩容自己独立的hashtable,扩容原理和hashmap是一样的。锁的实现采用的lock锁 + cas乐观锁 + UNSAFE类,似于 synchronized 锁的升级过程。支持多个Segment同时扩容

        大致原理就是将一个大的 HashMap 分成 n 多个不同的小的 HashTable,通过不同的 key 计算 index, 如果没有发生冲突 则存放到不同的小的 HashTable 中 ,从而可以实现多线程,但是如果多个线程同时做 put 操作 key 发 生了 index 冲突,落到同一个小的 HashTable 中还是会发生竞争锁。

底层原理:

1、由多个不同的segment对象组成

2、锁:lock锁

3、unsafe查询主内中最新的数据

4、使用cas做修改

1.8实现原理

        由数组 + 链表 + 红黑树组成的。取消了segments分段设计。

        ConcurrentHashmap是对index下标对应的node节点进行上锁,多个线程同时put key的时候,如果多个key都落入到同一个index node节点的时候,则需要做锁的竞争。

使用cas锁:index没有发生冲突,多个线程同时赋值的时候。

使用synchronized锁:index已经发生冲突,使用synchronized锁对该node节点上锁。

为什么1.8要去掉Segment分段锁?

因为1.7需要计算两次index,第一次计算存放在哪个segment对象里,第二次计算在哪个HashEntry里,

而1.8只需要计算一次index值。

为什么1.8使用synchroized锁,而不用lock锁?

lock锁是不带自旋功能的,synchorized自1.6后就自带短暂的自旋功能。

6、hashmap8核心参数

加载因子(default_load_factor=0.75f)用于提前扩容

初始容量(default_initial_capacity=1最大限制容量Maximum_capacity=1

链表长度(Treeify_threshold=8),链表长度如果大于8,则转换成红黑树

红黑树(untreeify_threshold=6),红黑树长度如果小于6,则转换成链表结构

数组容量(min_treeify_capacity=64)

modCount:遍历hashmap集合时,防止多线程对数据集合进行篡改

7、arraylist源码解读

1)扩容和缩容,数组默认初始容量为10.,扩容是1.5倍。

2)存放元素是有序的,线程不安全,没加锁的机制

3)get方法(index下标查询)、add方法。

4)数据结构基于数组的形式实现,类型是object类型,默认容量

8、arraylist和vector的区别

相同点:都是基于数组实现,默认初始容量也是10。

不同点:arraylist线程不安全,vector加的是synchroized锁,线程安全。

arraylist扩容是原容量的1.5倍,vector扩容是原容量的2倍。

9、hashset底层原理

底层基于hashmap集合实现(key是存储的这个对象,value是个空object),存储无序的,

底层数据结构也是 数组 + 链表 + 红黑树

hashmap集合中key是否允许重复?

不允许,比较hash值,hash值相等,并且equals不等的情况下,才能把这个值存进去。

10、linkedlist 原理

底层基于链表数据结构实现,底层是双向链表,保证下标有序性,采用尾插法,查找是折半算法(时间复杂度:log(n))

数组和链表的区别:

数组:保证元素有序性,可以基于下标查询,时间复杂度为O(1),适合于基于下标查询的场景,增删会对数组实现移动,效率低。

链表:单向链表、双向链表,可以基于下标查询,时间复杂度为O(n),适合于增删,只需要改引用指针的关系,查询的时候都得从头到尾查询。

标题基于SpringBoot+Vue的学生交流互助平台研究AI更换标题第1章引言介绍学生交流互助平台的研究背景、意义、现状、方法与创新点。1.1研究背景与意义分析学生交流互助平台在当前教育环境下的需求及其重要性。1.2国内外研究现状综述国内外在学生交流互助平台方面的研究进展与实践应用。1.3研究方法与创新点概述本研究采用的方法论、技术路线及预期的创新成果。第2章相关理论阐述SpringBoot与Vue框架的理论基础及在学生交流互助平台中的应用。2.1SpringBoot框架概述介绍SpringBoot框架的核心思想、特点及优势。2.2Vue框架概述阐述Vue框架的基本原理、组件化开发思想及与前端的交互机制。2.3SpringBoot与Vue的整合应用探讨SpringBoot与Vue在学生交流互助平台中的整合方式及优势。第3章平台需求分析深入分析学生交流互助平台的功能需求、非功能需求及用户体验要求。3.1功能需求分析详细阐述平台的各项功能需求,如用户管理、信息交流、互助学习等。3.2非功能需求分析对平台的性能、安全性、可扩展性等非功能需求进行分析。3.3用户体验要求从用户角度出发,提出平台在易用性、美观性等方面的要求。第4章平台设计与实现具体描述学生交流互助平台的架构设计、功能实现及前后端交互细节。4.1平台架构设计给出平台的整体架构设计,包括前后端分离、微服务架构等思想的应用。4.2功能模块实现详细阐述各个功能模块的实现过程,如用户登录注册、信息发布与查看、在线交流等。4.3前后端交互细节介绍前后端数据交互的方式、接口设计及数据传输过程中的安全问题。第5章平台测试与优化对平台进行全面的测试,发现并解决潜在问题,同时进行优化以提高性能。5.1测试环境与方案介绍测试环境的搭建及所采用的测试方案,包括单元测试、集成测试等。5.2测试结果分析对测试结果进行详细分析,找出问题的根源并
内容概要:本文详细介绍了一个基于灰狼优化算法(GWO)优化的卷积双向长短期记忆神经网络(CNN-BiLSTM)融合注意力机制的多变量多步时间序列预测项目。该项目旨在解决传统时序预测方法难以捕捉非线性、复杂时序依赖关系的问题,通过融合CNN的空间特征提取、BiLSTM的时序建模能力及注意力机制的动态权重调节能力,实现对多变量多步时间序列的精准预测。项目不仅涵盖了数据预处理、模型构建与训练、性能评估,还包括了GUI界面的设计与实现。此外,文章还讨论了模型的部署、应用领域及其未来改进方向。 适合人群:具备一定编程基础,特别是对深度学习、时间序列预测及优化算法有一定了解的研发人员和数据科学家。 使用场景及目标:①用于智能电网负荷预测、金融市场多资产价格预测、环境气象多参数预报、智能制造设备状态监测与预测维护、交通流量预测与智慧交通管理、医疗健康多指标预测等领域;②提升多变量多步时间序列预测精度,优化资源调度和风险管控;③实现自动化超参数优化,降低人工调参成本,提高模型训练效率;④增强模型对复杂时序数据特征的学习能力,促进智能决策支持应用。 阅读建议:此资源不仅提供了详细的代码实现和模型架构解析,还深入探讨了模型优化和实际应用中的挑战与解决方案。因此,在学习过程中,建议结合理论与实践,逐步理解各个模块的功能和实现细节,并尝试在自己的项目中应用这些技术和方法。同时,注意数据预处理的重要性,合理设置模型参数与网络结构,控制多步预测误差传播,防范过拟合,规划计算资源与训练时间,关注模型的可解释性和透明度,以及持续更新与迭代模型,以适应数据分布的变化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值