hashmap结构(hashmap构造函数)

http://www.itjxue.com  2023-02-12 09:42  来源:未知  点击次数: 

HashMap是什么东西

HashMap,中文名哈希映射,HashMap是一个用于存储Key-Value键值对的集合,每一个键值对也叫做Entry。这些个键值对(Entry)分散存储在一个数组当中,这个数组就是HashMap的主干。HashMap数组每一个元素的初始值都是Null。

HashMap是基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。

扩展资料:

因为HashMap的长度是有限的,当插入的Entry越来越多时,再完美的Hash函数也难免会出现index冲突的情况。

HashMap数组的每一个元素不止是一个Entry对象,也是一个链表的头节点。每一个Entry对象通过Next指针指向它的下一个Entry节点。当新来的Entry映射到冲突的数组位置时,只需要插入到对应的链表即可。

参考资料来源:

百度百科-Hashmap

1.8 hashMap 和CurrentHashMap结构

hashMap主要是 数组+链表+红黑树 ,1.7是 数组+链表

允许key 为null

1.8 HashMap put流程

1、计算key的hash值(高低位异或)

2、判断数组是否为空,如果数组为空 则直接扩容

3、如果数组非空 则 根据hash值计算数组下标(n-1) hash,根据下标取数组对应值,如果值为空则新建一个node,非空则转为下一步

4、key的hash 和 equals与 下标数组的值都相同,则直接覆盖;

5、如果不相同则 判断下标数组的值 是否 红黑树实例,是红黑树的话 新节点直接加入红黑树中

6、不是红黑树实例就是链表,循环遍历链表,并判断是否为已有节点如果有则直接返回,如果没有 则将新节点放到链表尾部,如果新链表大小超过 阈值(8-1)即= 7,将链表转为红黑树

7、key存储完毕之后,并判断 hashMap大小是否超阈值(上次map大小的2的次数),如果超过 则直接扩容,否则 put流程结束

1.8 ConcurrentHashMap put流程

1.8?ConcurrentHashMap 的数据结构和hashmap相同,不过处理方式上又有不同。

数据结构上是 数组+链表 +红黑树,但是 为了支持并发,又采取了 synchronized同步+ cas 模式来控制key的存放。

具体实现上 采用 被 volatile 修饰key value的node ,保证了并发的可见性。

从JDK1.7版本的ReentrantLock+Segment+HashEntry,到JDK1.8版本中synchronized+CAS+HashEntry+红黑树

并发行 是对 node节点 加同步锁 来保证 高效的插入。

put流程

1、key 或value 是否为空,任一为空直接返回空指针异常

2、非空,计算出key的hash值,高低位异或后 再与bit与操作

3、循环遍历数组,如果数组为空 则初始化数组主要?sizeCtl,非空则继续

4、数组非空,根据hash(n-1)下标值,取出数组对应的node,如果node为空 通过cas赋值

5、如果node非空,且node.hash 为moved,则扩容转移

6、否则,对取出的node加同步锁,如果此时内存的值未变(根据内存偏移取出的新值比较)如果 hash状态= 0,则循环遍历链表;若链表中已存在(通过hash和equals判断)则直接新值覆盖旧值;如果不存在 将新节点放入链表尾部。并记录链表大小 (binCount)

7、如果内存的值未变,如果 node是红黑树的实例,则将新node 放入红黑树中,如果红黑树中已存在,新值覆盖旧值。至此同步整个结束

8、另外 同步时候 有记录 binCount,如果binCount = 8,链表转红黑树处理

9、节点加入完成后,判断是否 需要扩容(转移),仅在无竞争情况下扩容

JDK1.8中的HashMap底层数据结构的图解

hashmap是java开发最常用的一种数据模型,hashmap属于map接口的一种实现。以key-value的这种形式存储数据,其中key是不允许重复的但是允许为空,value是可以重复或为空的。其中key只能使用基本数据类型(int,double...)的封装类(interger,double。。。。)。

JDK1.7中HashMap的底层是由数组+单向链表这两种数据结构组合而成的,而在JDK1.8中HashMap是由数组+单向链表+红黑树三种数据结构组合而成的。

初始化有固定的大小长度,有顺序的下标(下标从0开始),图1只是示例。

由每个节点组成,每个节点包含一个data(存储数据)和指向下一个节点地址的next,如图二。

(1)每个节点或者是黑色,或者是红色。

(2)根节点是黑色。

(3)每个叶子节点(NIL)是黑色。 注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点!

(4)如果一个节点是红色的,则它的子节点必须是黑色的。

(5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。

介绍完三种基本结构后,我们再来看看hashmap的数据结构图,如图4。

图5是我截自JDK1.8的HashMap底层源码。

(责任编辑:IT教学网)

更多

相关Frontpage教程文章

推荐Frontpage教程文章