一、前言

  本文由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. 原子操作CAS-最小的线程安全

    原文连接:(http://www.studyshare.cn/blog-front/blog/details/1166/0 )一.原子操作是什么? 如果有两个线程分别执行两个操作A和B,从第一个线程执 ...

  2. Hive学习之路(一)—— Hive 简介及核心概念

    一.简介 Hive是一个构建在Hadoop之上的数据仓库,它可以将结构化的数据文件映射成表,并提供类SQL查询功能,用于查询的SQL语句会被转化为MapReduce作业,然后提交到Hadoop上运行. ...

  3. Java 位域

    Java位域 这个概念是在 Effective Java中了解到的, 可以通过EnumSet来代替位域这种方式表达. 并不是很常见的概念, 因此记录下. 如果在这之前恰好了解过 bitmap这种数据结 ...

  4. T4生成实体和简单的CRUD操作

    主要跟大家交流下T4,我这里针对的是mysql,我本人比较喜欢用mysql,所以语法针对mysql,所以你要准备mysql的DLL了,同理sqlserver差不多,有兴趣可以自己写写,首先网上找了一个 ...

  5. 跟我学SpringCloud | 第十篇:服务网关Zuul高级篇

    SpringCloud系列教程 | 第十篇:服务网关Zuul高级篇 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如无特殊说明,本系列教程全 ...

  6. MYSQL手工注入(详细步骤)—— 待补充

    0x00 SQL注入的分类: (1)基于从服务器接收到的响应         ▲基于错误的 SQL 注入         ▲联合查询的类型         ▲堆查询注射         ▲SQL 盲注 ...

  7. Bean property 'transactionManagerBeanName' is not writable or has an invalid set

    [2017-02-07 11:38:48,458]-[localhost-startStop-1]-[org.springframework.beans.factory.support.Default ...

  8. Spark 中 RDD的运行机制

    1. RDD 的设计与运行原理 Spark 的核心是建立在统一的抽象 RDD 之上,基于 RDD 的转换和行动操作使得 Spark 的各个组件可以无缝进行集成,从而在同一个应用程序中完成大数据计算任务 ...

  9. NetworkError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load xxxx错误解决方法

    在开发项目的过程中,和后端对接,我们使用是一个成熟的集成很全面的架构JHipster.后端为java spring-boot 前端ts+react,需求是有一个需要在页面里嵌套iframe的需求.然后 ...

  10. mac环境下java项目无创建文件的权限

    1.问题: 先抛问题,由于刚刚换用mac环境,之前windows上开发的代码调试完毕,还未上线.之后上线部署之前,tl直连测试本地环境(mac)环境,功能无法使用,显示java.io.IOExcept ...