HashMap源码浅读

0 阅读须知


​ 学习过数据结构的童鞋一定对哈希表有所了解,Java1.7中的HashMap就是对数据结构中的哈希链表的实现,但是由于Java1.7中的HashMap存在着一些问题,故在Java1.8中做出了修改。本篇就让我们一起来通过学习Java中HashMap的源码来较为深入的理解hashMap的设计思路。

单词识记

单词 汉译
encapsulated 封装
load factor 负荷因子
capacity 容量

1 HashMap实现


  • JDK1.7中HashMap采用数组+链表的方式来实现最经典的哈希表
  • JDK1.8中为了应对JDK1.7中的一些问题,采用数组+链表+红黑树实现

注意:HashMap的容量必须是2^n默认是16,原因是HashMap中为了提高效率更快定位出key的位置,采用&运算来获取key对应数组的位置。下图是JDK1.8中源码:可以看出(n-1)&hash就是在这个关键点上。
HashMap源码浅读_第1张图片
HashMap源码浅读_第2张图片

JDK1.7问题

  1. 并发环境中易死锁
  2. 可以通过精心构造的恶意请求引发DoS,造成安全问题

引发以上问题的关键是在HashMap中占用的key数达到capacity*load factor时就开始扩容,在单线程下的扩容没有什么影响,但是在多线程下扩容就可能带来链环,如果正好get查询到了链环就进入了死循环。具体请参考:https://coolshell.cn/articles/9606.html

2 JDK1.8解决方案


​ 在JDK1.8中对HashMap进行扩容resize操作的时候,保证原有链表的前后顺序不能变,这样就可以有效的防止出现环形链表,但是HashMap仍然是线程不安全的。源码如下:(目前还没怎么看懂,但是从注释的来看就是保证了链表顺序)
HashMap源码浅读_第3张图片

注意:HashMap中的resize方法非常影响性能,尽量在创建之初提供较大的空间。

3 总结


​ 本篇从HashMap的源码入手,简单了解了一下JDK1.7–JDK1.8的变化,同时也提供了我们一个新的学习方法:阅读源码。

​ 不断提升自我,迭代自我,我是猿同学~~~

你可能感兴趣的:(JavaSE学习笔记)