一、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. Scala教程之:面向对象的scala

    文章目录 面向对象的scala Unified Types Classes Traits 面向对象的scala 我们知道Scala是一种JVM语言,可以合java无缝衔接,这也就大大的扩展了scala ...

  2. QQ网站的源代码

    链接:https://pan.baidu.com/s/1mqetTbauKTI0KJOaU8wW5A 提取码请加QQ:2669803073获取 声明:仅供学习,切勿用于其他用途

  3. 09-5.部署 EFK 插件

    09-5.部署 EFK 插件 EFK 对应的目录:kubernetes/cluster/addons/fluentd-elasticsearch $ cd /opt/k8s/kubernetes/cl ...

  4. ElementUI表单验证攻略:解决表单项启用和禁用验证的切换,以及动态表单验证的综合性问题

    试想一种比较复杂的业务场景: 表格(el-table)的每一行数据的第一列是勾选框,最后一列是输入框.当某一行的勾选框勾上时,启用该行的输入框,并开启该行输入框的表单验证:取消该行的勾选框,则禁用该行 ...

  5. 如何在Vue项目中优雅的使用swiper插件

    个人网站 https://iiter.cn 程序员导航站 开业啦,欢迎各位观众姥爷赏脸参观,如有意见或建议希望能够不吝赐教! 开始之前,请先确保有一个基于webpack模板的项目(vue-cli脚手架 ...

  6. CF思维联系–CodeForces - 225C. Barcode(二路动态规划)

    ACM思维题训练集合 Desciption You've got an n × m pixel picture. Each pixel can be white or black. Your task ...

  7. codeforce 270B Multithreading

    B. Multithreading Emuskald is addicted to Codeforces, and keeps refreshing the main page not to miss ...

  8. Java——Spring依赖配置详解

    <properties> <junit.version>4.12</junit.version> <spring.version>4.3.9.RELEA ...

  9. CC2530通用IO口的输入输出

    一.引脚概述 CC2530有40 个引脚.其中,有21个数字I/O端口,其中P0和P1是8 位端口,P2仅有5位可以使用.P2端口的5个引脚中,有2个需要用作仿真,有2个需要用作晶振.所以可供我们使用 ...

  10. LeetCode--Sort Array By Parity && N-Repeated Element in Size 2N Array (Easy)

    905. Sort Array By Parity (Easy)# Given an array A of non-negative integers, return an array consist ...