HashMap 在不同的 JDK 版本下的实现是不同的,在 JDK 1.7 时,HashMap 底层是通过数组 + 链表实现的;而在 JDK 1.8 时,HashMap 底层是通过数组 + 链表或红黑树实现的。

具体来说,HashMap 内部维护了一个数组,每个数组元素又是一个链表或者红黑树,每个链表或者红黑树节点存储了一个键值对。当需要存储新的键值对时,HashMap 会根据键的哈希值确定其在数组中的位置,如果该位置已经有了其他键值对,则通过链表或红黑树解决冲突,将新的键值对添加到链表或红黑树的末尾。当链表或红黑树长度达到一定程度后,HashMap 会自动将链表转换为红黑树,以提高查找效率。

如下图所示,HashMap 在 JDK 1.7 中的实现如下图所示:



在 JDK 1.8 时,HashMap 如下图所示:

链表和红黑树互转流程

链表升级为红黑树

在 JDK 1.8 之后,HashMap 默认是先使用数组 + 链表存储数据,但当满足以下两个条件时:

  1. 链表的数量大于阈值(默认是 8)
  2. 并且数组长度大于 64 时

为了(查询)的性能考虑会将链表升级为红黑树进行存储,具体执行流程如下:

  1. 创建新的红黑树对象,并将链表内所有的键值对全部添加到红黑树中。

  2. 将原来的链表引用指向新创建的红黑树。

红黑树退化为链表

当进行了删除操作,导致红黑树的节点小于等于 6 时,会发生退化,将红黑树转换为链表。这是因为当节点数量较少时,红黑树对性能的提升并不明显,反而占用了更多的内存空间。具体执行流程如下:

  1. 从红黑树的根节点开始,按照中序遍历的顺序将所有节点加入到一个新的链表中。

  2. 将原来的红黑树引用指向新创建的链表。

小结

HashMap 在 JDK 1.7 时,是通过数组 + 链表实现的,而在 JDK 1.8 时,HashMap 是通过数组 + 链表或红黑树实现的。在 JDK 1.8 之后,如果链表的数量大于阈值(默认为 8),并且数组长度大于 64 时,为了查询效率会将链表升级为红黑树,但当红黑树的节点小于等于 6 时,为了节省内存空间会将红黑树退化为链表。

本文已收录至《Java面试突击》,专注 Java 面试 100 年,查看更多:www.javacn.site

HashMap 底层是如何实现的?的更多相关文章

  1. hashMap底层put和get方法逻辑

    1.hashmap put方法的实现: public V put(K key, V value) { if (key == null) return putForNullKey(value); int ...

  2. ArrayList、LinkedList、HashMap底层实现

    ArrayList 底层的实现就是一个数组(固定大小),当数组长度不够用的时候就会重新开辟一个新的数组,然后将原来的数据拷贝到新的数组内. LinkedList 底层是一个链表,是由java实现的一个 ...

  3. HashMap底层实现原理

    HashMap底层实现 HashMap底层数据结构如下图,HashMap由“hash函数+数组+单链表”3个要素构成 通过写一个迷你版的HashMap来深刻理解 MyMap接口,定义一个接口,对外暴露 ...

  4. HashMap底层结构、原理、扩容机制

    https://www.jianshu.com/p/c1b616ff1130 http://youzhixueyuan.com/the-underlying-structure-and-princip ...

  5. HashMap 底层分析

    以下基于 JDK1.7 分析 如图所示,HashMap底层是基于数组和链表实现的,其中有两个重要的参数: ---容量 ---负载因子 容量的默认大小是16,负载因子是0.75,当HashMap的siz ...

  6. 最简单的HashMap底层原理介绍

    HashMap 底层原理  1.HashMap底层概述 2.JDK1.7实现方式 3.JDK1.8实现方式 4.关键名词 5.相关问题 1.HashMap底层概述 在JDK1.7中HashMap采用的 ...

  7. HashMap底层原理分析(put、get方法)

    1.HashMap底层原理分析(put.get方法) HashMap底层是通过数组加链表的结构来实现的.HashMap通过计算key的hashCode来计算hash值,只要hashCode一样,那ha ...

  8. HashMap底层原理

    原文出自:http://zhangshixi.iteye.com/blog/672697 1.    HashMap概述: HashMap是基于哈希表的Map接口的非同步实现.此实现提供所有可选的映射 ...

  9. HashMap底层数据结构和算法解析

    1.Hash Map的数据结构? A:哈希表结构(链表散列:数组+链表)实现,结合数组和链表的优点.当链表长度超过8时,链表转换为红黑树. transient Node<K,V>[] ta ...

  10. HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别(转)

    HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别 文章来源:http://www.cnblogs.com/beatIteWeNerverGiveU ...

随机推荐

  1. Tesseract5+OpenCV4(VS2017+win10)实现OCR识别

    一.环境配置 较之前采用cppan进行编译的方式,vcpkg的方式已经发生了许多变化,带来的最大不同就是便捷. 对于在NuGet中能够找到的Vcpkg的export,真的实现了开箱即用 这样的话对于普 ...

  2. 7.远程代码执行漏洞RCE

    远程代码执行漏洞RCE 1.RCE Remote Code Execute 远程代码执行 Remote Command Execute 远程命令执行 2.危害 窃取服务器的敏感数据.文件 对电脑的文件 ...

  3. MongoDB基础知识梳理

    简介 MongoDB 是由 C++ 编写的开源 NoSQL 和基于文档的数据库.MongoDB 提供了面向文档的存储方式,操作起来比较简单和容易,支持"无模式"的数据建模,可以存储 ...

  4. 阿里巴巴为什么这样强制从List中删除元素

    还是先举个例子,你侄女对天文知识感兴趣,然后你就用程序写了太阳系九大星系(水星.金星.地球.火星.木星.土星.天王星.海王星.冥王星)的运行轨迹图,然后拿给侄女看.然后她说错了错了,你的知识太旧了,多 ...

  5. 把一个列表拆成N个子列表的四种方法

    编程的方法往往不止一种,比如怎么把一个Python种的列表拆成N个子列表,我们可以很容易找到N种方法,也许这就是编程的魅力所在. 一.列表表达式法 这种方法最为简洁,不过可读性差一些 这个方法中,即使 ...

  6. LeeCode数组问题:二分查找

    LeeCode 704 二分查找 题目描述: 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标, ...

  7. day120:MoFang:修复宠物喂食饱食度不增加的BUG&修复宠物死亡导致数据错乱的BUG

    目录 BUG1:修复宠物喂食饱食度未增加的BUG BUG2:修复当用户拥有2个宠物时,如果第1个宠物挂了,会出现第二个宠物变成第1个宠物的情况,会导致数据发生混乱出现bug BUG1:修复宠物喂食饱食 ...

  8. MySQL(九)InnoDB行格式

    InnoDB行格式 查看默认行格式: select @@innodb_default_row_format; 查看数据库表使用的行格式 mysql> use atguigudb; Reading ...

  9. 【Spring注解驱动】(一)IOC容器

    前言 课程跟的是尚硅谷雷丰阳老师的<Spring注解驱动教程>,主要用于SSM框架向SpringBoot过渡,暑假有点懒散,争取这周看完. 1 容器 Spring的底层核心功能是IOC控制 ...

  10. 从热爱到深耕,全国Top10开源软件出品人手把手教你如何做开源

    摘要:DTT直播邀请到管雷鸣与广大开发者分享"如何在开源领域找到适合自己的路". "想象一下,你写的代码被越来越多的人使用,并极大地帮助他们提高了开发效率和稳定性.&qu ...