目录

HashMap底层原理

如何解决hash冲突?

HashMap为什么要用到链表结构?

HashMap为什么选择红黑树?

HashMap链表和红黑树在什么情况下转换的?

HashMap在什么情况下扩容?

HashMap是如何Put一个元素的 ?

HashMap是如何Get一个元素的?

你知道HahsMap死循环问题吗 ?


HashMap底层原理

HashMap底层是基于数组+链表+红黑树。

默认初始容量为(数组长度为**16),默认负载系数为0.75(这个表示的意思是扩容机制当容量达到75%的时候自动进行扩容(扩大一倍,扩容也是采用位运算【因为用乘法会影响CPU的性能,计算机不支持乘法运算,最终都会转化为加法运算[01的方式]。】),当扩容的时候,会创建新的数组,以前存放在数组中的数据将会重新通过hashCode进行排序,类似于hashCode/16取模【其实使用的是位运算,位运算效率更高】得到下标存放在对应的数组中,扩容后hashCode/32.)。

底层原理

1.先通过hash算法计算出当前键值hashCode值,然后对数组长度进行取余其实是位运算】,从而获得余数(即为下标)存储到对应的数组中【存储的是当前hash值(key计算的hash值),key,value和next】(所以HashMap存取数据元素是无序的)。[底层是位运算,性能更好,且可以更好的避免哈希碰撞]

2.通过下标存储键值时,如果当前下标没有存放其他键值时会直接存入,如果该下标处,已经存在其他键值时,则会发生哈希碰撞

3.发生哈希碰撞后,会继续比较下标处所有key的equals(内容)是否为true(来判断是不是同一个元素。)

如果是true,表示是相同的key,执行覆盖操作。

如果是false,表示是不同的key,执行在最后一个键值对后面追加操作,从而形成单向链表(链表的产生)。

4.如果链表长度>=8个且当前Map集合中数组长度>=64个,则会形成红黑树;如果当前数组长度<64个,则会扩容键值对数组(16*2),而且会重新进行排序。(并且会重新将所有键值对对32进行取余重新排序进行存储从而导致效率低

5.当调用remove方法的时候,会删除元素,当红黑树中剩余的键值对个数<=6个的时候,会重新还原成单向链表。(性能更好)

如何解决hash冲突

解决哈希冲突(四种方法)_君诀的博客-CSDN博客_解决哈希冲突的方法

  • 拉链法将产生hash碰撞的元素都链接到同一个链表中【形成链表结构】

  • 再Hash法将产生hash碰撞的元素再采用不同的哈希算法进行处理,直至没有哈希冲突

  • 建立公共溢出区把哈希表分为基本表和溢出表,将产生哈希冲突的元素存储到公共溢出表

  • 开放寻址法将产生hash碰撞的元素,去寻找一个新的空闲的哈希地址

开放寻址又包含了

1线性探测法:就是将在得到的hash值进行加1然后对数组长度取模,直到直到新的位置。

公式:h(x)=(Hash(x)+i)mod (Hashtable.length);(i会逐渐递增加1)

2平方探测法(二次探测):就是将在得到的hash值进行依次为+(i^2)和-(i^2)然后对数组长度取模,直到直到新的位置。

公式:h(x)=(Hash(x) +i)mod (Hashtable.length);(i依次为+(i^2)和-(i^2))

HashMap为什么要用到链表结构?

当我们向HashMap中添加元素时,会先根据key进行哈希运算,把hash值对数组长度进去取模(实际是位运算)得到一个下标,然后通过下标将元素进行存储。如果当前下标位置有数据就产生了哈希碰撞,进行equals比较内容是否相等,如果相等进行覆盖,如果不等,就会在用拉链法然后将这个数据追加到最后一个键值后面,最终形成单向链表。

HashMap为什么选择红黑树?

当HashMap中同一个索引位置出现哈希碰撞的元素多了,链表会变得越来越长查询效率会变得越来越慢。因此在JDK1.8之后,当链表长度超过8个,且数组长度>=64个的时候会将链表转坏为红黑树来提高查询

HashMap链表和红黑树在什么情况下转换的?

当链表的长度大于等于8,同时数组的长度大于等于64,链表会自动转化为红黑树,当树中的节点数小于64,红黑树会自动转化为链表

HashMap在什么情况下扩容?

        默认初始容量为(数组长度为**16),默认负载系数为0.75(这个表示的意思是扩容机制当容量达到75%的时候自动进行扩容(扩大一倍),当扩容的时候,会创建新的数组(数组中村的entry对象,key是对象通过hash算法运算后取模后的值,value是真正的对象),以前存放在数组中的数据将会重新通过hashCode进行排序 ,类似于hashCode/16取余得到下标存放在对应的数组中**,扩容后hashCode/32.)。

HashMap的扩容公式:initailCapacity * loadFactor 【负载因子】= HashMap

其中initailCapacity是初始容量:默认值为16(懒加载机制,只有当第一次put的时候才创建)

采用位运算的方式1*2的4次方

其中loadFactor是负载因子:默认值为0.75

默认扩大一倍。

HashMap是如何Put一个元素的

首先,将key进行hash运算,然后对数组长度进行取模(底层是位运算),计算出索引(下标)。此时判断该索引位置是否已经有元素了,如果没有,就直接放到这个位置。如果这个位置已经有元素了,也就是产生了哈希碰撞,那么判断旧元素的key和新元素的key的hash值是否相同,并且将他们进行equals比较,如果相同证明是同一个key,就覆盖旧数据,并将旧数据返回,如果不相同的话再判断当前桶是链表还是红黑树,如果是红黑树,就按红黑树的方式,写入该数据,如果是链表,就依次遍历并比较当前节点的key和新元素的key是否相同,如果相同就覆盖,如果不同就接着往下找,直到找到空节点并把数据封装成新节点挂到链表尾部。然后需要判断,当前链表的长度是否大于转化红黑树的阈值,如果大于就转化红黑树,最后判断数组长度是否需要扩容。

HashMap是如何Get一个元素的?

首先将key进行哈希运算,计算出数组中的索引位置,判断该索引位置是否有元素,如果没有,就返回null,如果有值,判断该数据的key是否为查询的key,如果是就返回当前值的value

如果第一个元素的key不匹配,判断是红黑树还是链表,如果是红黑树,就就按照红黑树的查询方式查找元素并返回,如果是链表,就遍历并匹配key,让后返回value值

你知道HahsMap死循环问题吗

HashMap在扩容数组的时候,会将旧数据迁徙到新数组中,这个操作会将原来链表中的数据颠倒,比如a->b->null,转换成b->a->null这个过程单线程是没有问题的,但是在多线程环境,就可,能会出现a->b->a->b....,这就是死循环

在JDK1.8后,做了改进保证了转换后链表顺序一致,死循环问题得到了解决。但还是会出现高并发时数据丢失的问题,因此在多线程情况下还是建议使用ConcurrentHashMap来保证线程安全问题

浅析HashMap底层原理相关推荐

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

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

  2. java map原理_Java HashMap底层原理分析

    前两天面试的时候,被面试官问到HashMap底层原理,之前只会用,底层实现完全没看过,这两天补了补功课,写篇文章记录一下,好记性不如烂笔头啊,毕竟这年头脑子它记不住东西了哈哈哈.好了,言归正传,今天我 ...

  3. HashMap底层原理(当你put,get时内部会发生什么呢?)

    HashMap底层原理解析(一) 接触过HashMap的小伙伴都会经常使用put和get这些方法,那接下来就对HashMap的内部存储进行详解.(以初学者的角度进行分析)-(小白篇) 当程序试图将多个 ...

  4. 深度解剖HashMap底层原理

    HashMap底层原理 写在前面 JDK1.7版本--HashMap java.1.7源码分析 new一个HashMap实例的存储流程图如下: API常用方法 API中重要的变量 第一步:申明一个Ha ...

  5. 我向面试官讲解了hashmap底层原理,他对我竖起了大拇指

    前言: 正值金九银十的黄金招聘期,大家都准备好了吗?HashMap是程序员面试必问的一个知识点,其内部的基本实现原理是每一位面试者都应该掌握的,只有真正地掌握了 HashMap的内部实现原理,面对面试 ...

  6. 面试官再问你 HashMap 底层原理,就把这篇文章甩给他看

    来自:烟雨星空 前言 HashMap 源码和底层原理在现在面试中是必问的.因此,我们非常有必要搞清楚它的底层实现和思想,才能在面试中对答如流,跟面试官大战三百回合.文章较长,介绍了很多原理性的问题,希 ...

  7. Java集合—HashMap底层原理

    原文链接:最通俗易懂搞定HashMap的底层原理 HashMap的底层原理面试必考题.为什么面试官如此青睐这道题?HashMap里面涉及了很多的知识点,可以比较全面考察面试者的基本功,想要拿到一个好o ...

  8. hashMap 底层原理+LinkedHashMap 底层原理+常见面试题

    1.源码 java1.7 hashMap 底层实现是数组+链表 java1.8 对上面进行优化 数组+链表+红黑树 2.hashmap 是怎么保存数据的. 在hashmap 中有这样一个结构 Node ...

  9. 查询已有链表的hashmap_面试官再问你 HashMap 底层原理,就把这篇文章甩给他看...

    前言 HashMap 源码和底层原理在现在面试中是必问的.因此,我们非常有必要搞清楚它的底层实现和思想,才能在面试中对答如流,跟面试官大战三百回合.文章较长,介绍了很多原理性的问题,希望对你有所帮助~ ...

  10. hashmap底层原理_周末自己动手撸一个 HashMap,美滋滋

    对HashMap的思考 通过写一个迷你版的HashMap来深刻理解 定义接口 接口实现 看MyHashMap的构造 Entry 看put如何实现 hash函数 resize和rehash get实现 ...

最新文章

  1. Java线上问题排障:Linux内核bug引发JVM死锁导致线程假死
  2. 据说程序员等电梯的时候都想过调度算法
  3. IOS开发错误library not found for -lXXX
  4. Java Scoket之java.io.EOFException解决方案
  5. 通讯录(容量不可变)
  6. 【云上技术】中大型规模企业如何部署多数据中心?
  7. Jquery-基础知识点
  8. [ASP.NET笔记] 5.验证控件
  9. 《JavaScript 高级程序设计》 7.1 正则表达式支持
  10. java obix_obix协议在java中的配置和使用详解
  11. LeetCode 794. 有效的井字游戏(分类讨论)
  12. CSS和JS两种颜色渐变文字效果代码
  13. Postman中json内字符串转义问题
  14. python之--工具类方法
  15. LayaAir cacheAs 缓存与 visible 隐藏
  16. 2016-2017 ACM Central Region of Russia Quarterfinal Programming Contest
  17. 前端FISH框架学习笔记
  18. 小白从零开发鸿蒙小游戏(1)“数字华容道”—【深鸿会学习小组学习心得及笔记】
  19. VsCode——创建Vue 模板
  20. 第三方支付平台:微信支付接口

热门文章

  1. 计算机毕业设计jspm平面设计类众包威客网网站mjmBBmysql程序
  2. 那些开挂的人,如何打败50%的竞争者?
  3. 人工智能中常用的词汇
  4. “真正的机器人测试” - 淘宝泛终端机器人自动化测试实践
  5. Linux下VirtualBox出现kernel driver not installed的解决方法
  6. 怎么解决图片用PSCC打开后,白色部分全部呈现米黄色?
  7. 区块链--大白话说明
  8. java做抽奖小程序_随机抽奖小程序
  9. Unity3D流体插件FluidSim使用总结
  10. TM1640的驱动及代码