一、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的源码浅析的更多相关文章

  1. HashSet其实就那么一回事儿之源码浅析

    上篇文章<HashMap其实就那么一回事儿之源码浅析>介绍了hashMap,  本次将带大家看看HashSet, HashSet其实就是基于HashMap实现, 因此,熟悉了HashMap ...

  2. java并发:jdk1.8中ConcurrentHashMap源码浅析

    ConcurrentHashMap是线程安全的.可以在多线程中对ConcurrentHashMap进行操作. 在jdk1.7中,使用的是锁分段技术Segment.数据结构是数组+链表. 对比jdk1. ...

  3. 【深入浅出jQuery】源码浅析--整体架构

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  4. 【深入浅出jQuery】源码浅析2--奇技淫巧

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  5. Struts2源码浅析-ConfigurationProvider

    ConfigurationProvider接口 主要完成struts配置文件 加载 注册过程 ConfigurationProvider接口定义 public interface Configurat ...

  6. (转)【深入浅出jQuery】源码浅析2--奇技淫巧

    [深入浅出jQuery]源码浅析2--奇技淫巧 http://www.cnblogs.com/coco1s/p/5303041.html

  7. Android 手势识别类 ( 三 ) GestureDetector 源码浅析

    前言:上 篇介绍了提供手势绘制的视图平台GestureOverlayView,但是在视图平台上绘制出的手势,是需要存储以及在必要的利用时加载取出手势.所 以,用户绘制出的一个完整的手势是需要一定的代码 ...

  8. Android开发之Theme、Style探索及源码浅析

    1 背景 前段时间群里有伙伴问到了关于Android开发中Theme与Style的问题,当然,这类东西在网上随便一搜一大把模板,所以关于怎么用的问题我想这里也就不做太多的说明了,我们这里把重点放在理解 ...

  9. 【深入浅出jQuery】源码浅析2--使用技巧

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

随机推荐

  1. Java阻塞队列四组API介绍

    Java阻塞队列四组API介绍 通过前面几篇文章的学习,我们已经知道了Java中的队列分为阻塞队列和非阻塞队列以及常用的七个阻塞队列.如下图: 本文来源:凯哥Java(kaigejava)讲解Java ...

  2. certutil 导入 CA 证书

    2019独角兽企业重金招聘Python工程师标准>>> 在linux下使用GoAgent客户端的时候,需要导入CA.cer证书. 安装证书管理工具 apt-get install l ...

  3. WordPress发布文章/页面时自动添加默认的自定义字段

    如果你每篇文章或页面都需要插入同一个自定义字段和值,可以考虑在WordPress发布文章/页面时,自动添加默认的自定义字段.将下面的代码添加到当前主题的 functions.php 即可: 1 2 3 ...

  4. IO与反射机制总结

    IO与反射机制全面总结 一.file类:属于java.io包中kkb 作用:操作文件或目录 file既可以表示文件,也可以表示目录,也可以表示盘符.利用他可以用来对文件进行操作. file中常用的构造 ...

  5. linux 服务器/客户端 tcp通信的简单例子

    昨天弄了sublime之后没有弄输入中文的了,学生党来着,刚好可以练练英语(英语渣渣,还要考六级),所以注释都写英文的(语法什么的就别太深究了) 服务器端: /*start from the very ...

  6. 7) 项目准备流程 和 django权限六表

    一.项目准备 1. 创建django项目 2. 创建数据库 —— init文件中声明mysql —— settings中配置数据库 import pymysql pymysql.install_as_ ...

  7. 07_CSS入门和高级技巧(5)

    超级链接美化 1.伪类 同一个超级链接,根据用户的点击情况,有自己样式: 超级链接根据用户点选情况,有4种状态: a:link 没有访问的超级链接 a:visited 已经访问的超级链接 a:hove ...

  8. 真香!PySpark整合Apache Hudi实战

    1. 准备 Hudi支持Spark-2.x版本,你可以点击如下链接安装Spark,并使用pyspark启动 # pyspark export PYSPARK_PYTHON=$(which python ...

  9. [hdu2112]最短路

    相当于模板题了,用trie来完成字符串到数字的映射比map<string, int>要快不少,令外可以考虑hash. 运行时间对比: (1)(2)600ms左右 (3)3000ms左右(4 ...

  10. Spring Cloud认知学习(一):Spring Cloud介绍与Eureka使用

    目录 Spring Cloud的介绍 微服务的介绍 Spring Cloud出现的原因: 常见场景: 微服务的优劣势: Spring Cloud版本问题 版本介绍 与Spring Boot版本对应关系 ...