美文网首页
HashMap快速理解

HashMap快速理解

作者: 詠遠鍀飛哥 | 来源:发表于2018-01-03 15:07 被阅读22次

参考文章

1.https://www.toutiao.com/a6496248960213058062/
2.https://www.zhihu.com/question/20733617/answer/111577937

基本知识:

1.HashMap默认数组长度

 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // 16

2.负载英子默认值

static final float DEFAULT_LOAD_FACTOR = 0.75f;

最重要的是元素插入的位置和key的hash值有关

static final int hash(Object key) {
    int h;
    //扰动函数,确保h的高位和低位都参与hash运算,减少偶发性
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

哈希散列性的体现

当length为2的幂次方时候,(length - 1) & h 即 h % length 位运算的效率高很多

 static final int indexFor(int h, int length){
           return h & (length - 1);
  }

源码分析

Java7源码分析

先决条件:
先决条件
put操作:
put操作

先看上面key为空的情况(上面画图的时候总要在第一格留个空key的键值对),执行 putForKey 方法单独处理,会把该键值对放在index0,所以HashMap中是允许key为空的情况。再看下主流程:

步骤①.根据键值算出hash值 — > hash(key)

步骤②.根据hash值和当前数组的长度计算在数组中的索引 — > indexFor(hash, table.length)

步骤③情况1.hash值和key值都相同,替换原来的值,并将被替换的值返回。

步骤③情况2.坑位没人或发生hash碰撞 — > addEntry(hash, key, value, i)

如果put的时候超过阀值,会调用 resize 方法将数组大小扩大为原来的2倍,并且根据新表的长度计算在新表中的索引(如之前17%16 =1,现在17%32=17),看下resize方法

上面的重点是步骤②,看下它具体的转移操作

Java7 put流程图

Java7 put流程图

Java8源码分析

初始化
iJava8 put的源码
Java8 put的源码
通过上面注释分析,对比和Java7的区别,Java8一视同仁,管你key为不为空的统一处理,多了一步链表长度的判断以及转红黑树的操作,并且比较重要的一点,新增Node是插在尾部而不是头部!!!
扩容resize操作
扩容resize操作

可以看到,Java8把初始化数组和扩容全写在resize方法里了

JDK1.8做了哪些优化

经过观测可以发现,我们使用的是2次幂的扩展(指长度扩为原来2倍),所以,元素的位置要么是在原位置,要么是在原位置再移动2次幂的位置。看下图可以明白这句话的意思,n为table的长度,图(a)表示扩容前的key1(5)和key2(21)两种key确定索引位置的示例,图(b)表示扩容后key1和key2两种key确定索引位置的示例,其中hash1是key1对应的哈希与高位运算结果。


hash扩容

图a中key1(5)和key(21)计算出来的都是5,元素在重新计算hash之后,因为n变为2倍,那么n-1的mask范围在高位多1bit(红色),因此新的index就会发生这样的变化:

图解HashMap(一)

Java8 put流程图

Java8 put流程图

对比总结

1.发生hash冲突时,Java7会在链表头部插入,Java8会在链表尾部插入
2.扩容后转移数据,Java7转移前后链表顺序会倒置,Java8还是保持原来的顺序
3.引入红黑树的Java8大程度得优化了HashMap的性能

相关文章

  • HashMap快速理解

    参考文章 1.https://www.toutiao.com/a6496248960213058062/2.htt...

  • HashMap源码理解

    HashMap理解 HashMap定义 HashMap实现机制 HashMap与HashTable的主要区别 关键...

  • 深入理解HashMap(文末附带源码)

    点关注,不迷路! 快速开始 HashMap相信大家在日常的开发中都用过,首先我们快速回忆下。 hashmap在我们...

  • HashMap理解

    来源:牛课网a) HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。HashMap的底层结...

  • hashMap理解

    1.环境 jdk:1.8 1.1 介绍 本文介绍将讨论开发中最流行java集合框架中实现map接口HashMap,...

  • HashMap 理解

    参考链接:HashMap原理深入理解java中HashMap原理?面试?你是谁,你在哪 HashMap实际上是一个...

  • HashMap理解

    hashmap在jdk1.7和1.8上是有区别的,在1.7上是数组+链表的形式,在1.8上是数组+链表+红黑树的形...

  • 给Python程序员的Scala入门教程

    快速语法对照 List HashMap Set For loop Range

  • HashMap原理解析

    HashMap 原理解析 hashmap构造hashmap 默认的初始数组容量大小为16,默认加载因子为0.75,...

  • Java集合-HashSet源码实现分析

    概要 阅读本文前,请先阅读笔者写的文章:Java集合-HashMap源码实现深入解析理解了HashMap,再来理解...

网友评论

      本文标题:HashMap快速理解

      本文链接:https://www.haomeiwen.com/subject/rnhqnxtx.html