一、前言

  本文由jdk1.8源码整理而得,附自制jdk1.8底层数据结构图,并截取部分源码加以说明结构关系。

二、jdk1.8 HashMap底层数据结构图

  

三、源码

  1.散列表(Hash table,也叫哈希表):

    /**
* 表,第一次使用时初始化(而非实例化集合时进行初始化),并根据需要调整大小。当分配时,长度总是2的幂。(在某些操作中,我们还允许长度为零,以允许当前不需要的引导机制。)
   */
transient Node<K,V>[] table;

  2.链表:

    /**
* Basic hash bin node, used for most entries. (See below for
* TreeNode subclass, and in LinkedHashMap for its Entry subclass.)
*/
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
V value;
Node<K,V> next;
     ……
}

  3.红黑树:

    /**
* Entry for Tree bins. Extends LinkedHashMap.Entry (which in turn
* extends Node) so can be used as extension of either regular or
* linked node.
*/
static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> {
TreeNode<K,V> parent; // red-black tree links
TreeNode<K,V> left;
TreeNode<K,V> right;
TreeNode<K,V> prev; // needed to unlink next upon deletion
boolean red;
……
}

四、问题探究

  1.散列表后面跟的“链表、红黑树”是怎么来的,都解决了哪些问题?

    答:

    ①链表的由来:Hash碰撞:不同的元素通过hash算法可能会得到相同的hash值,如果都放同一个桶里,后面放进去的就会覆盖前面放的,所以为了解决hash碰撞时元素被覆盖的问题,就有了在桶里放链表。

    ②红黑树的由来:假设现在HashMap集合中大多数的元素都放到了同一个桶里(由hash值计算而得的桶的位置相同),那么这些元素就在这个桶后面连成了链表。现在需要查询某个元素,那么此时的查询效率就很慢了,它是在做链表查询( O(N) 的查询效率)。为了解决这个问题,就引入了红黑树( log(n) 的查询效率):当链表到达一定长度时就在链表的后面创建红黑树。

    ③其实,“尽量避免hash 冲突,让元素较为均匀的放置到每个桶”才是查询效率最高的( O(1) 的查询效率),这和hash算法的实现息息相关,这里不做深究。

  2.如图可知,散列表后面跟的数据结构有可能是链表,也有可能是红黑树。散列表后面跟什么数据结构是怎么确定的?

    答:

    ①链表节点转换成红黑树节点的阈值, 节点数 >= 8 就转:

      static final int TREEIFY_THRESHOLD = 8;

    ②红黑树节点转换链表节点的阈值, 节点数 <= 6 就转:

      static final int UNTREEIFY_THRESHOLD = 6;

    ③转红黑树时, table的最小长度:

      static final int MIN_TREEIFY_CAPACITY = 64;

jdk1.8HashMap底层数据结构:散列表+链表+红黑树,jdk1.8HashMap数据结构图解+源码说明的更多相关文章

  1. Map集合、散列表、红黑树介绍

    前言 声明,本文用得是jdk1.8 前面已经讲了Collection的总览和剖析List集合: Collection总览 List集合就这么简单[源码剖析] 原本我是打算继续将Collection下的 ...

  2. Java HashMap源码分析(含散列表、红黑树、扰动函数等重点问题分析)

    写在最前面 这个项目是从20年末就立好的 flag,经过几年的学习,回过头再去看很多知识点又有新的理解.所以趁着找实习的准备,结合以前的学习储备,创建一个主要针对应届生和初学者的 Java 开源知识项 ...

  3. [数据结构与算法]RED-BLACK(红黑)树的实现TreeMap源码阅读

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  4. 红黑树插入操作---以JDK 源码为例

    红黑树遵循的条件: 1.根节点为黑色. 2.外部节点(叶子节点)为黑色. 3.红色节点的孩子节点为黑色.(由此,红色节点的父节点也必为黑色) 4.从根节点到任一外部节点的路径上,黑节点的数量相同. 节 ...

  5. jdk1.8 HashMap 实现 数组+链表/红黑树

    转载至 http://www.cnblogs.com/leesf456/p/5242233.html 一.前言 在分析jdk1.8后的HashMap源码时,发现网上好多分析都是基于之前的jdk,而Ja ...

  6. [数据结构1.2-线性表] 动态数组ArrayList(.NET源码学习)

    [数据结构1.2-线性表] 动态数组ArrayList(.NET源码学习) 在C#中,存在常见的九种集合类型:动态数组ArrayList.列表List.排序列表SortedList.哈希表HashTa ...

  7. 运行OpenGL红宝书第9版源码时Visual Studio提示“无法启动程序...ALL_BUILD。拒绝访问“的问题的解决办法

    问题描述: OpenGL红宝书第9版源码采用CMake编译后,用相应的Visual Studio(如VS2012)打开“vermilion9.sln”解决方案,并运行时Visual Studio提示“ ...

  8. Python数据结构——散列表

    散列表的实现常常叫做散列(hashing).散列仅支持INSERT,SEARCH和DELETE操作,都是在常数平均时间执行的.需要元素间任何排序信息的操作将不会得到有效的支持. 散列表是普通数组概念的 ...

  9. 数据结构---散列表查找(哈希表)概述和简单实现(Java)

    散列表查找定义 散列技术是在记录的存储位置和它的关键字之间建立一个确定的对应关系f,是的每个关键字key对应一个存储位置f(key).查找时,根据这个确定的对应关系找到给定值的key的对应f(key) ...

随机推荐

  1. 07 jQuery的位置信息

    一.宽度和高度 获取宽度 .width() 描述:为匹配的元素集合中获取第一个元素的当前计算宽度值.这个方法不接受任何参数..css(width) 和 .width()之间的区别是后者返回一个没有单位 ...

  2. spark 2.x在windows环境使用idea本地调试启动了kerberos认证的hive

    1 概述 开发调试spark程序时,因为要访问开启kerberos认证的hive/hbase/hdfs等组件,每次调试都需要打jar包,上传到服务器执行特别影响工作效率,所以调研了下如何在window ...

  3. Hadoop —— 集群环境搭建

    一.集群规划 这里搭建一个3节点的Hadoop集群,其中三台主机均部署DataNode和NodeManager服务,但只有hadoop001上部署NameNode和ResourceManager服务. ...

  4. CTF干货合集

    CTF练习平台 http://hackinglab.cn/ 网络信息安全攻防学习平台 http://captf.com/ ctf题目 http://oj.xctf.org.cn/ XCTF_OJ练习平 ...

  5. 【python3两小时根本不够】入门笔记04:线程+Lock安全同步

    有了简单爬虫,但是效率实在是太慢,于是决定启用线程进行爬取数据 但是对于临界资源的定义不好把握,思路如下: 1.定义队列(Queue的数据结构,List也可,安全性待考究) demo:https:// ...

  6. Python中的函数及函数参数的使用

    函数:一个工具,随调随用 降级代码冗余 增加代码的复用性,提高开发效率,为了不成为cv战士 提高程序扩展性 函数有两个阶段:定义阶段,调用阶段. 定义时:只检查函数体内代码语法,不执行函数体内代码. ...

  7. 微信小程序在ios下Echarts图表不能滑动的解决方案

    问题现象 这个问题的现象说起来很简单. 小程序页面中有一篇很长的文章,内部有一个Echarts图表,手指上下滑动观看内容. 但是手指滑动区域在Echarts图表上时,页面却不能滑动了. 如下图: 追踪 ...

  8. 源码阅读 - java.util.concurrent (四)CyclicBarrier

    CyclicBarrier是一个用于线程同步的辅助类,它允许一组线程等待彼此,直到所有线程都到达集合点,然后执行某个设定的任务. 举个例子:几个人约定了某个地方集中,然后一起出发去旅行.每个参与的人就 ...

  9. HDU 1724:Ellipse(自适应辛普森积分)

    题目链接 题意 给出一个椭圆,问一个[l, r] 区间(蓝色区域)的面积是多少. 思路 自适应辛普森积分 具体一些分析如上. 很方便,套上公式就可以用了. 注意 eps 的取值影响了跑的时间,因为决定 ...

  10. 那些有实力进入 BAT 的本科生,都做对了什么事?

    作者:黄小斜 文章来源:微信公众号[黄小斜] 最近这段时间,我们部门来了几个年纪轻轻的本科生,最小的比我们小五岁左,这对于我来说还是比较有冲击力的. 想想我也是九0出头的老腊肉了,想当年我上大学的时候 ...