小编给大家分享一下HashMap源码学习及7/8对比的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
Jdk1.7的HashMap实质上是一个Entry数组,数组的每个元素是一个单向链表,其数据结构如下:
HashMap的put方法:
判断map中的数组是否是空的,是则初始化数组。(可见HashMap在构造函数的时候其实啥都没干,真正初始化数组的时候是在put方法执行的)
判断key值是否为null,为null则将值放入在数组的第一个元素即table[0]
根据key计算出hash值
通过hash值从table数组找到对应的下表
取数组table对应下标的链表并遍历判断是否存在相同key值,存在则覆盖旧值并返回
key值不存在则将Entry添加到链表中
仔细看看addEntry方法的实现,主要流程如下:
首先判断当前size是否已经达到了阈值且对应数组小标已经有值则需要扩容,扩容一定是数组大小的2倍,扩容后重新计算元素在新数组里的下表
在数组对应下表添加新的原色(新添加元素一定是添加都链表的表头,将next指向旧值)
HashMap的get方法
判断key值是否为空,为空直接从数据的第一个元素返回值
根据key计算出hash,根据hash找到对应数组下表,然后在根据hash从对应链表中取值即可
HashMap存在的非线程安全的问题:
扩容时候形成环形链表
添加数据时数据丢失
HashMap1.8相比1.7有比较大的改进,数据结构由1.7的数组+链表修改为数组+链表+红黑树,其中当链表的元素大于等于8的时候会转换成红黑树存储,另外就是扩容的时间点,1.7是先扩容再添加元素,1.8是先添加元素后再扩容。其数据结构由1.7的Entry数组变为Node数组,如:
put方法主要代码如下:
get方法,相对比较简单:
通过key计算出hash值,然后找到对应数组的下表 2.判断对应下表的第一个值是否就是要找的对应key值,若是,直接返回,否则进行第3步
判断元素是链表还是红黑树,然后相应的获取对应的值。
两个版本采用的存储结构不同,一个是数组+链表,一个是数组+链表+红黑树
扩容顺序不同,1.7是先扩容再插入,1.8是先插入在扩容
1.8中链表转红黑树的条件是链表长度大于等于8 4.均不是线程安全
以上是“HashMap源码学习及7/8对比的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。