概述
HashMap基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。
值得注意的是HashMap不是线程安全的,如果想要线程安全的HashMap,可以通过Collections类的静态方法synchronizedMap获得线程安全的HashMap。( Map map = Collections.synchronizedMap(new HashMap());)
数据结构
HashMap的底层主要是基于数组和链表来实现的,它之所以有相当快的查询速度主要是因为它是通过计算散列码来决定存储的位置。HashMap中主要是通过key的hashCode来计算hash值的,只要hashCode相同,计算出来的hash值就一样。如果存储的对象对多了,就有可能不同的对象所算出来的hash值是相同的,这就出现了所谓的hash冲突。HashMap底层是通过链表来解决hash冲突的。
源码分析
HashMap类中的一些关键属性
transient Entry[] table;//存储元素的实体数组
transient int size;//存放元素的个数
int threshold; //临界值 当实际大小超过临界值时,会进行扩容threshold = 加载因子*容量
final float loadFactor; //加载因子
transient int modCount;//被修改的次数
加载因子越大,填满的元素越多,好处是,空间利用率高了,但:冲突的机会加大了.链表长度会越来越长,查找效率降低。反之,加载因子越小,填满的元素越少,好处是:冲突的机会减小了,但:空间浪费多了.表中的数据将过于稀疏(很多空间还没用,就开始扩容了)冲突的机会越大,则查找的成本越高.取默认值0.75。初始容量是16,容量为2的n次幂。
存储数据
put方法
若“key为null”,则将该键值对添加到table[0]中。
若“key不为null”,则计算该key的哈希值i,然后将其添加到该哈希值对应的链表中。
搜索指定hash值在对应table中的索引
循环遍历Entry数组,若“该key”对应的键值对已经存在,则用新的value取代旧的value。然后退出!
修改次数+1
将key-value添加到table[i]处
如果要加入的位置有值,将该位置原先的值设置为新entry的next,也就是新entry链表的下一个节点
get方法
首先计算key的hashCode,找到数组中对应位置的某一元素,
然后通过遍历key的equals方法在对应位置的链表中找到需要的元素。
HashMap的性能参数:
HashMap 包含如下几个构造器:
HashMap():构建一个初始容量为 16,负载因子为 0.75 的 HashMap。
HashMap(int initialCapacity):构建一个初始容量为 initialCapacity,负载因子为 0.75 的 HashMap。
HashMap(int initialCapacity, float loadFactor):以指定初始容量、指定的负载因子创建一个 HashMap。
HashMap的基础构造器HashMap(int initialCapacity, float loadFactor)带有两个参数,它们是初始容量initialCapacity和加载因子loadFactor。
initialCapacity:HashMap的最大容量,即为底层数组的长度。
loadFactor:负载因子loadFactor定义为:散列表的实际元素数目(n)/ 散列表的容量(m)。
Fail-Fast机制:
ava.util.HashMap不是线程安全的,如果在使用迭代器的过程中有其他线程修改了map,那么将抛出ConcurrentModificationException,这就是所谓fail-fast策略
这一策略在源码中的实现是通过modCount域,modCount就是修改次数,对HashMap内容的修改都将增加这个值,那么在迭代器初始化过程中会将这个值赋给迭代器的expectedModCount。在迭代过程中,判断modCount跟expectedModCount是否相等,如果不相等就表示已经有其他线程修改了Map:modCount声明为volatile,保证线程之间修改的可见性。
分享到:
相关推荐
HashMap原理解析
HashMap原理简介,Java初学者
一线大厂BATJ面试题讲解-hashmap原理实现
详细分析HashMap的存储原理,key值的hash地址以及扩容
hashmap的底层及源码解析,很适合大家的学习,不要积分。
HashMap是一个散列桶(数组和链表),它存储的内容是键值对(key-value)映射HashMap采用了...而Hashtable则不能(原因就是equlas()方法需要对象,因为HashMap是后出的API经过处理才可以)2、HashMap的工作原理是什么?
hashmap的扩容原理以及如何扩容,部分源码的分析。希望对大家有所帮助
主要介绍了对HashMap原理的理解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
hashMap基本工作原理,图解分析,基础Map集合
详细介绍了hashMap原理,值得一看,对于面试者有很大帮助
本文主要介绍了java无锁hashmap原理与实现,大家参考使用吧
主要介绍了Java HashMap原理及实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
本教程特点: 1.更适合零基础学员: ·自Java语言起源始,循序渐进,知识点剖析细致且每章配备大量随堂练习,让你步步为营,学得透彻、练得明白 ·拒绝晦涩难懂的呆板教学,宋老师语言生动幽默,举例形象生动深入浅...
HashMap底层原理.md
HashMap底层原理
文章目录一.HashMap是什么二.HashMap继承类对比分析三.HashMap源码相关单词含义四.HashMap如何确定哈希桶数组索引位置五. HashMap 的 put 方法分析六.HashMap扩容机制七.HashMap线程安全性 一.HashMap是什么 ...
对HashMap 源码逐行进行注释,带你深入理解HashMap原理,使面试不在困难,
hashMap基本工作原理,图解分析,基础Map集合
HashMap底层实现原理HashMap与HashTable区别HashMap与HashSet区别。HashMap、HashTable和HashSet是Java中常用的数据结构,它们的底层实现原理以及区别如下:HashMap底层实现原理: HashMap基于哈希表(HashTable)...
HashMap的实现原理