看懂了JDK7Hashmap的扩容头插法,及其可能产生的循环引用问题,今天看看JDK8的HashMap扩容实现。采取的是用四个结点,两条链表完成重新分配位置,比较简单有趣。解析如下:

 //如果原来的table等于null,直接返回if (oldTab != null) {//遍历原来的table,bucketfor (int j = 0; j < oldCap; ++j) {HashMap.Node<K, V> e;//bucketif ((e = oldTab[j]) != null) {//如果当前桶位上有元素,不为nulloldTab[j] = null;//当前位置置空if (e.next == null)//如果只有一个元素e,e.next为null,直接安排e到新表新家newTab[e.hash & (newCap - 1)] = e;else if (e instanceof HashMap.TreeNode)//判断e是不是树形节点,也就是超过8个元素((HashMap.TreeNode<K, V>) e).split(this, newTab, j, oldCap);//else { // preserve orderHashMap.Node<K, V> loHead = null, loTail = null;//低位的头结点,尾结点HashMap.Node<K, V> hiHead = null, hiTail = null;//高危的头结点,尾结点HashMap.Node<K, V> next;//下个节点do {//在这个循环里,依次处理该桶上链表,分裂成高位链和低位链next = e.next;//后一个节点元素//如果元素的hash值,与 原来表的容量 等于0,实际上是把原来在一个桶位的元素分流//例如e.hash & 10000,值会有0和1两种,等于0的,还是相对于原表的索引位置//等于1,把他向高位调整if ((e.hash & oldCap) == 0) {if (loTail == null)//只有第一次进来的时候,loTail为nullloHead = e;//设置头结点位eelseloTail.next = e;//尾插loTail = e;//低位链指针下移} else {if (hiTail == null)hiHead = e;elsehiTail.next = e;hiTail = e;}} while ((e = next) != null);//while循环完之后,大概会形成两个链表【高位链hiHead--hiTail,低位链loHead--loTail】,最极端的情况是只有高位链或//只有低位链。拿着这两个链表,插入到对应桶位,入驻新家。//判断低位链中是否有元素if (loTail != null) {loTail.next = null;//干掉低位链尾部的next,因为e的下一个结点很可能被分到高位,所以我们要干掉这个叛徒newTab[j] = loHead;}//判断高位链中是否有元素if (hiTail != null) {hiTail.next = null;newTab[j + oldCap] = hiHead;}}}}}

JDK8HashMap的扩容核心解读,尾插法相关推荐

  1. HashMap扩容机制以及尾插法

    1. resize定义 当HashMap中的元素越来越多的时候,碰撞的几率也就越来越高(因为数组的长度是固定的),所以为了提高查询的效率,就要对HashMap的数组进行扩容,数组扩容这个操作也会出现在 ...

  2. Hashmap扩容时出现循环链表(jdk1.8把头插法换成了尾插法的原因)

    参考:https://blog.csdn.net/sinat_39410753/article/details/106242573 1.容量计算 容量的阈值=容量*加载因子 2.扩容容量 扩容的容量大 ...

  3. HashMap面试题 头插法、尾插法、hash冲突、数组扩容、ConcurrentHashMap

    文章目录 HashMap 的数据结构? HashMap 的工作原理? HashMap 的 table 的容量如何确定?loadFactor 是什么?该容量如何变化?这种变化会带来什么问题? 数组扩容的 ...

  4. 数据结构学习(二)——单链表的操作之头插法和尾插法创建链表

    http://blog.csdn.net/abclixu123/article/details/8210109 链表也是线性表的一种,与顺序表不同的是,它在内存中不是连续存放的.在C语言中,链表是通过 ...

  5. 头插法和尾插法总结(动图版)

    代码使用结构体: typedef struct Node{int value;struct Node* next; }*Link; 头插法:利用头指针控制链表节点的增加. 核心: newNode-&g ...

  6. 创建链表:头插法与尾插法

    两种方法的区别无非是插入的位置: 头插法:新插入结点始终未当前的第一个结点 尾插法:新插入结点始终为当前的最后一个结点 头插法建表 实现代码: //头插法建链表 void HeadCreateList ...

  7. hashmap头插法和尾插法区别

    前言 HashMap 应该算是 Java 后端工程师面试的必问题,因为其中的知识点太多,很适合用来考察面试者的 Java 基础. 开场 面试官: 你先自我介绍一下吧! 安琪拉: 我是安琪拉,草丛三婊之 ...

  8. 18.链表插入——尾插法

    链表插入--尾插法 核心思想 核心代码 注意 示例 核心思想 找到要插到后方的节点 new->next = p->next p->next = new 核心代码 void inser ...

  9. 图解java链表基本操作篇一(头插法和尾插法)

    整体代码结构定义 public class LinkedListTest <E>{} 节点数据存储定义 这样子定义只是为了可以方便地创建双向链表,循环链表,不影响单链表的创建,在创建链表的 ...

最新文章

  1. python 开始学习
  2. 开学无望!13家高校宣布:期末考试线上进行!
  3. 关于操作系统中进程、线程、死锁、同步、进程间通信(IPC)的超详细详解整理
  4. linux下覆盖文件命令,在Linux中使用命令行进行文件覆盖的操作
  5. 【第一篇】Volley的使用之json请求
  6. JAVA基础之列表(list)和字典(dict)
  7. 程序员面试金典——番外篇之下一个较大元素I
  8. BIGWORLD问题集
  9. android控制电脑,安卓手机远程控制电脑教程详解
  10. 网线水晶头 RJ45 接法
  11. 苹果se2_太快了!苹果已面向iPhone SE 2用户推送iOS 13.4.1
  12. PADS VX.2.7 + OrCAD 16.5 + AutoCAD 2020 使用教程
  13. pygame小游戏——中国地图拼图小游戏
  14. 数据结构之图(二)——邻接矩阵
  15. opencv-python识别魔方特定颜色方块,并输出各方块中心坐标
  16. LabVIEW热敏电阻温度计程序
  17. linux关闭后台所有jinch,Centos查看端口占用情况和开启端口命令
  18. 三子棋(井字棋)小游戏
  19. Elastic Job入门示例
  20. mac hdmi 不能调整音量_用快捷键调节 Mac 外接显示器亮度:MonitorControl

热门文章

  1. 安卓 linux找回内置存储,Android手机自带内部存储路径的获取
  2. 【OpenCV 例程200篇】33. 图像的复合变换
  3. python安装常见问题_Python常见问题
  4. python能做什么效果_python对于做SEO主要有什么作用?
  5. git上传分支的原理_GIT分支,创建分支与合并分支的工作原理与教程
  6. Win10调试ssd_tensorflow的目标检测
  7. 教你配置安全的ProFTPD服务器(中)
  8. Factors of Factorial AtCoder - 2286 (N的阶乘的因子个数)(数论)
  9. 【学习总结】GirlsInAI ML-diary day-11-while循环
  10. 解决Gradle生成Eclipse支持后,发布到Tomcat丢失依赖jar包的问题