final Node<K,V>[] resize() {
//创建一个Node数组用于存放table中的元素,
Node<K,V>[] oldTab = table;
//获取旧table的长度
int oldCap = (oldTab == null) ? 0 : oldTab.length;
//获取旧的扩容阈值
int oldThr = threshold;
int newCap, newThr = 0;
//如果旧的table中有元素
if (oldCap > 0) {
//如果旧table长度>=最大容量限制时不进行扩容,并将扩容阈值赋值为Integer.MAX_VALUE
if (oldCap >= MAXIMUM_CAPACITY) {
threshold = Integer.MAX_VALUE;
return oldTab;
}
// 将新table长度赋值为旧table的2倍,
// 判断旧table长度的二倍是否小于最大容量,且旧容量大于等于初始容量,
// 以上判断成立则将新的扩容阀值赋值为旧的扩容阈值的二倍
else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
oldCap >= DEFAULT_INITIAL_CAPACITY)
newThr = oldThr << 1; // double threshold
}
else if (oldThr > 0) // initial capacity was placed in threshold
newCap = oldThr;
else { // zero initial threshold signifies using defaults
newCap = DEFAULT_INITIAL_CAPACITY;
newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);
}
if (newThr == 0) {
float ft = (float)newCap * loadFactor;
newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?
(int)ft : Integer.MAX_VALUE);
}
threshold = newThr; @SuppressWarnings({"rawtypes","unchecked"})
//将旧table中的元素放到扩容后的newTable中
Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
table = newTab;
if (oldTab != null) {
for (int j = 0; j < oldCap; ++j) {
Node<K,V> e;
if ((e = oldTab[j]) != null) {
oldTab[j] = null;
//如果数组对应下标位置只有一个元素,对hashCade取余并根据结果直接放到newTable相应的位置
if (e.next == null)
newTab[e.hash & (newCap - 1)] = e;
//如果数组对应下标位置的元素是一个红黑树,则拆分红黑树放到newTable中
// 如果拆分后的红黑树元素小于6,则转化为链表
else if (e instanceof TreeNode)
((TreeNode<K,V>)e).split(this, newTab, j, oldCap);
else { // preserve order
//数组对应下标位置的元素是一个链表的情况
//根据(e.hash & oldCap)条件对链表进行拆分并放到newTable
Node<K,V> loHead = null, loTail = null;
Node<K,V> hiHead = null, hiTail = null;
Node<K,V> next;
do {
next = e.next;
if ((e.hash & oldCap) == 0) {
if (loTail == null)
loHead = e;
else
loTail.next = e;
loTail = e;
}
else {
if (hiTail == null)
hiHead = e;
else
hiTail.next = e;
hiTail = e;
}
} while ((e = next) != null);
if (loTail != null) {
loTail.next = null;
newTab[j] = loHead;
}
if (hiTail != null) {
hiTail.next = null;
newTab[j + oldCap] = hiHead;
}
}
}
}
}
return newTab;
}

HashMap源码之resize的更多相关文章

  1. HashMap 源码解析

    HashMap简介: HashMap在日常的开发中应用的非常之广泛,它是基于Hash表,实现了Map接口,以键值对(key-value)形式进行数据存储,HashMap在数据结构上使用的是数组+链表. ...

  2. HashMap源码分析

    最近一直特别忙,好不容易闲下来了.准备把HashMap的知识总结一下,很久以前看过HashMap源码.一直想把集合类的知识都总结一下,加深自己的基础.我觉的java的集合类特别重要,能够深刻理解和应用 ...

  3. JAVA源码分析-HashMap源码分析(一)

    一直以来,HashMap就是Java面试过程中的常客,不管是刚毕业的,还是工作了好多年的同学,在Java面试过程中,经常会被问到HashMap相关的一些问题,而且每次面试都被问到一些自己平时没有注意的 ...

  4. Java集合---HashMap源码剖析

    一.HashMap概述二.HashMap的数据结构三.HashMap源码分析     1.关键属性     2.构造方法     3.存储数据     4.调整大小 5.数据读取           ...

  5. 【转】Java HashMap 源码解析(好文章)

    ­ .fluid-width-video-wrapper { width: 100%; position: relative; padding: 0; } .fluid-width-video-wra ...

  6. 【JAVA集合】HashMap源码分析(转载)

    原文出处:http://www.cnblogs.com/chenpi/p/5280304.html 以下内容基于jdk1.7.0_79源码: 什么是HashMap 基于哈希表的一个Map接口实现,存储 ...

  7. HashMap源码剖析

    HashMap源码剖析 无论是在平时的练习还是项目当中,HashMap用的是非常的广,真可谓无处不在.平时用的时候只知道HashMap是用来存储键值对的,却不知道它的底层是如何实现的. 一.HashM ...

  8. Java中HashMap源码分析

    一.HashMap概述 HashMap基于哈希表的Map接口的实现.此实现提供所有可选的映射操作,并允许使用null值和null键.(除了不同步和允许使用null之外,HashMap类与Hashtab ...

  9. 转:【Java集合源码剖析】HashMap源码剖析

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/36034955   您好,我正在参加CSDN博文大赛,如果您喜欢我的文章,希望您能帮我投一票 ...

随机推荐

  1. 系统休眠消息PBT_APMSUSPEND

    https://msdn.microsoft.com/en-us/library/windows/desktop/aa372721(v=vs.85).aspx https://msdn.microso ...

  2. python常用点小记

    记录一下,经常用到的一些python小工具 1.验证一个字符串是否为url regex = re.compile( r'^(?:http|ftp)s?://' # http:// or https:/ ...

  3. Geoserver发布Image Mossaic图层

    1数据准备:请事先在arcgis desktop软件中将栅格数据拼接完毕,并为每一幅影像生成一个prj文件,坐标系一定是要有的,不然Mossaic图层发布不了. 2."数据存储“->& ...

  4. Java NIO 学习笔记(一)----概述,Channel/Buffer

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  5. 系统学习 Java IO (二)----IO 异常处理

    目录:系统学习 Java IO---- 目录,概览 我们使用流后,需要正确关闭 Streams 和 Readers / Writers . 这是通过调用 close() 方法完成的,看看下面这段代码: ...

  6. 【朝花夕拾】Android自定义View篇之(五)Android事件分发机制(上)Touch三个重要方法的处理逻辑

    前言 转载请注明,转自[https://www.cnblogs.com/andy-songwei/p/10998855.html]谢谢! 在自定义View中,经常需要处理Android事件分发的问题, ...

  7. throw 与 throws的比较

    说实话,今天在公司的实习,确确实实编号被严重打脸了,说真的,自己的基础功不扎实,希望慢慢弥补吧! 抛出异常有三种形式,一是throw,一个throws,还有一种系统自动抛异常,下面它们之间的异同. 一 ...

  8. 我的那些年(12)~公司技术转行,我也跟着转到java了

    回到目录 我的那些年(12)~公司技术转行,我也跟着转到java了 CTO换人了 微软技术栈不被认可经常被喷 技术统一向java转 换了mac book后,docker还是很占内存 学习springb ...

  9. 浅谈SpringBoot

    关于SpringBoot有哪些特性,SpringBoot官网是这么描述的: Features Create stand-alone Spring applications Embed Tomcat, ...

  10. NetCore 中间件获取请求报文和返回报文

    using System; using System.IO; namespace WebApi.Restful.Middlewares { public class MemoryWrappedHttp ...