HashMap源码学习及7/8对比的示例分析

小编给大家分享一下HashMap源码学习及7/8对比的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

成都创新互联公司长期为上千余家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为隆安企业提供专业的网站设计制作、网站设计,隆安网站改版等技术服务。拥有10余年丰富建站经验和众多成功案例,为您定制开发。

HashMap1.7

Jdk1.7的HashMap实质上是一个Entry数组,数组的每个元素是一个单向链表,其数据结构如下:HashMap源码学习及7/8对比的示例分析

HashMap的put方法:

  1. 判断map中的数组是否是空的,是则初始化数组。(可见HashMap在构造函数的时候其实啥都没干,真正初始化数组的时候是在put方法执行的)

  2. 判断key值是否为null,为null则将值放入在数组的第一个元素即table[0]

  3. 根据key计算出hash值

  4. 通过hash值从table数组找到对应的下表

  5. 取数组table对应下标的链表并遍历判断是否存在相同key值,存在则覆盖旧值并返回

  6. key值不存在则将Entry添加到链表中 HashMap源码学习及7/8对比的示例分析

仔细看看addEntry方法的实现,主要流程如下:

  1. 首先判断当前size是否已经达到了阈值且对应数组小标已经有值则需要扩容,扩容一定是数组大小的2倍,扩容后重新计算元素在新数组里的下表

  2. 在数组对应下表添加新的原色(新添加元素一定是添加都链表的表头,将next指向旧值) HashMap源码学习及7/8对比的示例分析 HashMap源码学习及7/8对比的示例分析 HashMap源码学习及7/8对比的示例分析

HashMap的get方法

  1. 判断key值是否为空,为空直接从数据的第一个元素返回值

  2. 根据key计算出hash,根据hash找到对应数组下表,然后在根据hash从对应链表中取值即可 HashMap源码学习及7/8对比的示例分析

HashMap存在的非线程安全的问题:

  1. 扩容时候形成环形链表

  2. 添加数据时数据丢失

HashMap1.8

HashMap源码学习及7/8对比的示例分析

HashMap1.8相比1.7有比较大的改进,数据结构由1.7的数组+链表修改为数组+链表+红黑树,其中当链表的元素大于等于8的时候会转换成红黑树存储,另外就是扩容的时间点,1.7是先扩容再添加元素,1.8是先添加元素后再扩容。其数据结构由1.7的Entry数组变为Node数组,如: HashMap源码学习及7/8对比的示例分析

put方法主要代码如下: HashMap源码学习及7/8对比的示例分析

HashMap源码学习及7/8对比的示例分析

get方法,相对比较简单:

  1. 通过key计算出hash值,然后找到对应数组的下表 2.判断对应下表的第一个值是否就是要找的对应key值,若是,直接返回,否则进行第3步

  2. 判断元素是链表还是红黑树,然后相应的获取对应的值。 HashMap源码学习及7/8对比的示例分析

  1. 两个版本采用的存储结构不同,一个是数组+链表,一个是数组+链表+红黑树

  2. 扩容顺序不同,1.7是先扩容再插入,1.8是先插入在扩容

  3. 1.8中链表转红黑树的条件是链表长度大于等于8 4.均不是线程安全

以上是“HashMap源码学习及7/8对比的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注创新互联行业资讯频道!


当前题目:HashMap源码学习及7/8对比的示例分析
路径分享:http://myzitong.com/article/pjipie.html