HashMap的源码浅析
一、HashMap 的数据结构
Java7 及之前主要是“数组+链表”,到了 Java8 之后,就变成了“数组+链表+红黑树”。
二、Java7 源码浅析:
在Java7 中,HashMap 是数据结构里学的 HashTable 经典的实现!
注意点:Java7 中的 HashMap 当我们new出来的时候,他就给我们初始化了底层的 Entry 数组!
1、HashMap()

它自行调用了一个有参的构造器,并传入了默认的数组长度和负载因子:


2、put()
大致流程:先根据 key 的哈希值获取数组索引,然后挨个在数组上查找是否有Entry key 哈希值和值都和 put 的 key 相同,有的话就覆盖 value 了;没有的话,才进行 Entry 的添加!


3、indexFor()
在这里获取数组索引,哈希值 &(数组长度-1),这也就是为什么数组长度为 2 的幂的原因!

4、addEntry()
在添加节点的时候,会进行是否扩容的判断!

三、Java7 中的问题:
- 死锁:头插法。因为复制的时候,依次把链表元素复制到新的数组中去,有可能部分元素获取的数组索引还是相同的,因为头插法会导致链表导致,从而形成环形链表,当CPU下次进入这个链表查询时,产生死锁!
- 安全隐患:Apache Tomcat 底层是使用哈希表来进行存储 Http request 的 parameters,如果此时http请求中的参数中有大量 hash 相同的 key,那么可能导致服务器中形成大量的环形链表,消耗大量CPU,发生Dos!2011年的时候 Tomcat 察觉到并临时想到了一个方法,提供了一个参数,用于限制参数的个数,默认值是 1W!而 Java8 在2014年的时候发布的时候,
四、Java8 的源码浅析:
HashMap()


put()
注意:此时,分配数组索引已经是在判断的时候做的了!

Java 8 相对于 7 的变化:
- new HashMap() 时,底层没有第一时间创建 默认长度的数组!
- 底层是 Node 数组,而非 Entry 数组
- 首次调用 put 方法的时候,才进行数组的创建!(延时加载)
- put 时,如果添加新节点的话,采用的是尾插法!(可避免 7 的死锁问题!)
- 7 的底层结构只有 数组+链表,8 则是 数组+链表+红黑树(当 put 的链表长度等于8,且数组长度等于 64 的时候,这个链表就会转为红黑树结构!)!
HashMap的源码浅析的更多相关文章
- HashSet其实就那么一回事儿之源码浅析
上篇文章<HashMap其实就那么一回事儿之源码浅析>介绍了hashMap, 本次将带大家看看HashSet, HashSet其实就是基于HashMap实现, 因此,熟悉了HashMap ...
- java并发:jdk1.8中ConcurrentHashMap源码浅析
ConcurrentHashMap是线程安全的.可以在多线程中对ConcurrentHashMap进行操作. 在jdk1.7中,使用的是锁分段技术Segment.数据结构是数组+链表. 对比jdk1. ...
- 【深入浅出jQuery】源码浅析--整体架构
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- 【深入浅出jQuery】源码浅析2--奇技淫巧
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- Struts2源码浅析-ConfigurationProvider
ConfigurationProvider接口 主要完成struts配置文件 加载 注册过程 ConfigurationProvider接口定义 public interface Configurat ...
- (转)【深入浅出jQuery】源码浅析2--奇技淫巧
[深入浅出jQuery]源码浅析2--奇技淫巧 http://www.cnblogs.com/coco1s/p/5303041.html
- Android 手势识别类 ( 三 ) GestureDetector 源码浅析
前言:上 篇介绍了提供手势绘制的视图平台GestureOverlayView,但是在视图平台上绘制出的手势,是需要存储以及在必要的利用时加载取出手势.所 以,用户绘制出的一个完整的手势是需要一定的代码 ...
- Android开发之Theme、Style探索及源码浅析
1 背景 前段时间群里有伙伴问到了关于Android开发中Theme与Style的问题,当然,这类东西在网上随便一搜一大把模板,所以关于怎么用的问题我想这里也就不做太多的说明了,我们这里把重点放在理解 ...
- 【深入浅出jQuery】源码浅析2--使用技巧
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
随机推荐
- Spring5参考指南: Resources
文章目录 内置Resource实现 ResourceLoader ResourceLoaderAware 资源作为依赖 构造ClassPathXmlApplicationContext-快捷方式 资源 ...
- build.gradle 详解(一)
简述: 1) Java 开发中有两个大名鼎鼎的项目构建 ANT.Maven. 2) Google 推荐使用的 Android studio 是采用 Gradle 来构建项目.Gradle 是一个非常先 ...
- Spring Boot 整合 Spring Security,用户登录慢
场景 Spring Boot + Spring Security搭建一个Web项目. 临时用了inMemoryAuthentication. @EnableWebSecurity public cla ...
- Linux hostname主机名查看和设置
查询主机名: uname -n hostname [root@oldboy ~]# uname -n oldboy [root@oldboy ~]# hostname oldboy Linux操作系统 ...
- 看了就会的VScode给C++的配置编译环境(Visual Studio Code)
我看了网上的大佬们配的我是在是看不懂啊?我是一个小白啊?这太难了,这阻挡不了我,想使用这很骚的IDE,于是在不断的摸索下,终于配置成功,小白们也不用慌,这次非常简单.一定可以的. 1.下载 VS Co ...
- HDOJ 4699 Editor 对顶栈模拟
Editor Time Limit: 3000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Total Subm ...
- RF(用例执行方法)
一.执行 RF 脚本方法 1.执行整个项目下的所有用例 dos 窗口下输入 robot + 项目绝对路径 2.执行单个 Suite 中的所有用例 dos 窗口下输入 robot + 用例套件绝对路径 ...
- 单调队列+二分 G - Queue 小阳买水果
B. Queue 这个题目会做的很偶然,突然想到的,因为我们要求离这只海象的最远的比他年轻的海象,这个年轻的海象可以用单调栈维护. 就是从前往后遍历一遍,单调栈里面存年龄从小往大的海象,这个为什么这么 ...
- java基础篇 之 异常丢失
我们看如下代码: @Slf4j public class Test { public static void main(String[] args) { try { try { test(); } f ...
- HTTP接口测试
HTTP接口测试 1.1 get接口 请求URL http://api.nnzhp.cn/api/user/stu_info 请求方式 get 请求参数 参数名 必选 类型 说明 stu_name 是 ...