jdk1.8 HashMap数据结构

              图1-HashMap类图                    图2-TreeNode类图    

由图1-HashMap类图可知HashMap底层数据结构是由一个Node<K,V>的数组构成。具体Node<K,V>究竟是何数据结构暂且不讨论,先看一下HashMap最重要的两个方法之一put()方法的具体实现

public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
   //table为HashMap成员变量,具体可见图1,
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
   //没有发生hash碰撞,直接创建一个新节点存放在复制给tab[i]
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
   //发生hash碰撞
else {
Node<K,V> e; K k;
     //判断p节点是否为目标节点
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
     //如果图1中Node<K,V>类型为TreeNode(红黑树),就直接调用红黑树的putTreeVal方法查找目标节点
else if (p instanceof TreeNode)
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
else {
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
            //如果原来链表的长度>=TREEIFY_THRESHOLD-1(TREEIFY_THRESHOLD值为8),将链表转换成红黑树存储
p.next = newNode(hash, key, value, null);
            //如果原来链表的长度>=TREEIFY_THRESHOLD-1(TREEIFY_THRESHOLD值为8),将链表转换成红黑树存储
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
          //如果e节点为目标节点
if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))
break;
          //将p节点指向e节点继续下一次循环
p = e;
            }
}
     //e不为空表面找到了目标节点,替换原来的值即可
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
}
  //e为空,表面目标节点不存在,HashMap的size加一,modCount加一
++modCount;
  //如果size加1后超过了阀值则进行扩容
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
} 由以上put方法的源代码再结合图2-TreeNode类图可以看出HashMap的数据结构具体如图3
1.当HashMap外层是一个数组
2.数组里面是一个链表(链表长度<=7时)
3.当链表长度>7时,则将链表转化成红黑树
  

图三-HashMap数据结构

jdk1.8源码解析(1):HashMap源码解析的更多相关文章

  1. 源码解析之HashMap源码

    关于HashMap的源码分析,网上已经有很多写的非常好的文章了,虽然多是基于java1.8版本以下的.Java1.8版本的HashMap源码做了些改进,理解起来更复杂点,但也不脱离其桶+链表或树的重心 ...

  2. [java源码解析]对HashMap源码的分析(二)

    上文我们讲了HashMap那骚骚的逻辑结构,这一篇我们来吹吹它的实现思想,也就是算法层面.有兴趣看下或者回顾上一篇HashMap逻辑层面的,可以看下HashMap源码解析(一).使用了哈希表得“拉链法 ...

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

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

  4. 【Java集合源码剖析】HashMap源码剖析

    转载出处:http://blog.csdn.net/ns_code/article/details/36034955 HashMap简介 HashMap是基于哈希表实现的,每一个元素是一个key-va ...

  5. [java源码解析]对HashMap源码的分析(一)

    最近有空的时候研究了下HashMap的源码,平时我用HashMap主要拿来当业务数据整理后的容器,一直觉得它比较灵活和好用, 这样 的便利性跟它的组成结构有很大的关系. 直接开门见山,先简要说明一下H ...

  6. 【源码分析】HashMap源码再读-基于Java8

    最近工作不是太忙,准备再读读一些源码,想来想去,还是先从JDK的源码读起吧,毕竟很久不去读了,很多东西都生疏了.当然,还是先从炙手可热的HashMap,每次读都会有一些收获.当然,JDK8对HashM ...

  7. 【jdk源码3】HashMap源码学习

    可以毫不夸张的说,HashMap是容器类中用的最频繁的一个,而Java也对它进行优化,在jdk1.7及以前,当将相同Hash值的对象以key的身份放到HashMap中,HashMap的性能将由O(1) ...

  8. Java 源码刨析 - HashMap 底层实现原理是什么?JDK8 做了哪些优化?

    [基本结构] 在 JDK 1.7 中 HashMap 是以数组加链表的形式组成的: JDK 1.8 之后新增了红黑树的组成结构,当链表大于 8 并且容量大于 64 时,链表结构会转换成红黑树结构,它的 ...

  9. Java集合类源码解析:HashMap (基于JDK1.8)

    目录 前言 HashMap的数据结构 深入源码 两个参数 成员变量 四个构造方法 插入数据的方法:put() 哈希函数:hash() 动态扩容:resize() 节点树化.红黑树的拆分 节点树化 红黑 ...

  10. hashmap源码解析,JDK1.8和1.7的区别

    背景:hashmap面试基础必考内容,需要深入了解,并学习其中的相关原理.此处还要明白1.7和1.8不通版本的优化点. Java 8系列之重新认识HashMap Java 8系列之重新认识HashMa ...

随机推荐

  1. 五、stdout,stdoin和stderr

    stdout,stdin和stderr分别是标准输出流.标准输入流和标准错误流,当一个用户进程被创建的时候,系统会自动为该进程创建这三个数据流,默认情况下这三个流是在终端上表现出来的.可以使用fpri ...

  2. ThreadPoolExecutor使用

    构造方法参数讲解  参数名 作用 corePoolSize 核心线程池大小 maximumPoolSize 最大线程池大小 keepAliveTime 线程池中超过corePoolSize数目的空闲线 ...

  3. shell脚本定义输出字符颜色

    #-------------------定义输入颜色---------------------# RED='\033[1;31m' GREEN='\033[1;32m' YELLOW='\033[1; ...

  4. mssqlserver超级班助类 带详细用法

    using System; using System.Collections; using System.Collections.Generic; using System.Configuration ...

  5. UVA548 tree的思路

    唔,首先这题给出了中序遍历和后序遍历要求我们求出, 一个叶子节点到根的数值总和最小,且这个叶子节点是最小的那个 这题的难点在于如何运用中序遍历和后序遍历还原整棵树, 这里有两个方法: 1. 递归构造原 ...

  6. (a ==1 && a== 2 && a==3) 有可能是 true 吗?

    工作之余逛知乎的时候看到一个有意思的讨论,(a ==1 && a== 2 && a==3) 有可能是 true 吗?啊?一个变量同时满足三个条件?扯呢? 当然是我太天真 ...

  7. java8-lambda常用语法示例

    常用语法示例: public static void main(String[] args) { List<OrderInfo> orderInfoList = Lists.newArra ...

  8. Sql 查询当天、本周、本月记录、上周、上月记录

    查询当天: select * from info where DateDiff(dd,datetime,getdate())=0 查询24小时内: select * from info where D ...

  9. 常用且难记的一些css

    1.多行文字超出隐藏,自动追加 ... 移动端兼容更好,pc下只能兼容 Safari.Opera 以及 Chrome 等部分浏览器,挺常用. (注:为什么要同时加这几个css不在这里详细叙述,详见) ...

  10. Python学习之路基础篇--08Python基础+ 文件的基本操作和 注册小作业

    1 文件的基本操作 #1. 打开文件的模式有(默认为文本模式): r ,只读模式[默认模式,文件必须存在,不存在则抛出异常] w,只写模式[不可读:不存在则创建:存在则清空内容] a, 只追加写模式[ ...