【数据结构】JDK HashMap源码解析

news/2024/11/30 1:46:22/

目录

🌟HashMap源码解析

🌈类的属性

🌈构造方法

🌈put方法

🌟对比常用Map的子类实现:


🌟HashMap源码解析

        JDK8之前,HashMap就是数组+链表;

        JDK8之后,变成了数组+链表+红黑树。

问题1:什么时候会进行树化操作呢?

(1)当某个子链表的长度>=8并且整个哈希表的元素个数>=64时才会将当前的链表进行树化操作。

(2)若子链表的长度>=8但是哈希表的元素个数不满足大于等于64时,会进行整表扩容(也就是简单的将数组进行扩容)

        接下来我们主要从以下三部分来了解源码。

🌈类的属性

🌈构造方法

1、无参构造:只是初始化负载因子

  2、有参构造

(1)一个参数的有参构造

(2)两个参数的有参构造

         可以看见,在定义构造函数的时候,无论hi无参还是有参,这两种方式都并没有将数组容量进行初始化,那什么时候进行数组的初始化呢?我们接下来继续看。

🌈put方法(重点)

        HashMap最核心的代码就在于它的put方法。

问题2:请解释Object类的hashCode与equals的关系与区别?

  • equals类是判断两个对象的内容是否相同;
  • hashCode:默认的hashCode会将对象地址映射为整型,需要将任意数据类型转化Wie整型。

🆚区分:

(1)两个对象的hashCode返回相同的数值,equals是否返回true? 

        两个对象的hashCode虽然返回的数值相同,但是不同的数字经过哈希函数运算完全是有可能得到相同的索引值的,因此很有可能不是同一个对象,所以equals不一定相同;

(2)两个对象的equals方法返回true,hashCode是否返回相同的数值? 

        这其实也就是前文说到的哈希函数设计中的稳定性,一个相同的值经过哈希函数得到的值一定是相同的,因此两个对象是一样的,经过hashCode计算得到的值一定是相同的。

注意:若需要用到哈希方法,需要对默认的Object进行重写,因为我们需要使用对象的属性值来计算HashCode,而不是地址值。

        你分清了吗?😁 我们接下来继续看put方法~

 图太丑了🤣大家多看几遍理一理~通过上述,我们可以解决前文提出的问题:那就是数组容量是在第一次调用put方法时初始化的。这种现象叫做懒加载。我们顺便对put方法做一个小结~

🚨 put方法的核心流程小结:
(1)如果hashMap还没有初始化,就先进行哈希表的初始化操作(默认初始化容量是16)

(2)对传入的key值做哈希运算,得到要存放在数组中的索引位置

        如果此时还没有发生哈希碰撞,将该节点头插到数组中

        如果已经发生碰撞,判断此时是树还是链表形式:

                如果是链表形式,就将该节点作为链表的最后一个节点插入

                如果链表已经树化,就将该节点构造为树节点后再计入红黑树

(3)如果哈希表中存在key值,就只需要更新value值即可

(4)同时在更新元素个数的时候判断是否需要扩容。


🌟对比常用Map的子类实现:

TreeMapHashMap
内部数据结构RBTree哈希表
key和value是否可以为空

key:    ✅

value: ❎

        key必须具备可比较的性质或者传入比较器对象

key:    ✅

value: ✅

是否有序对于key“有序”,这个大小关系由Comparable或者比较器对象决定无序
是否线程安全不安全不安全

注意:若需要线程安全的Map集合,使用java.util.ConcurrentHashMap。



http://www.ppmy.cn/news/59033.html

相关文章

基础的文件操作

目录 ❤ 什么是文件? ❤ 为什么要有文件? ❤ 如何用文件? 从硬盘中读取数据 写入数据 ❤ 总结 python从小白到总裁完整教程目录:https://blog.csdn.net/weixin_67859959/article/details/129328397?spm1001.2014.3001.5502 虽然视…

【看表情包学Linux】软硬链接

🤣 爆笑教程 👉 《看表情包学Linux》👈 猛戳订阅 🔥 💭 写在前面:上面我们学到的所有东西,全部都是在内存中的。是不是所有的文件都被打开了呢?不是所有的文件,都被打开…

​kali下搭建WiFi钓鱼热点​

在linux下建立无线热点并不像在windows下开启网络共享或者使用无线网卡驱动设置AP模式即可。 linux下的无线共享要用到两个软件:hostapd(创建无线热点)、dnsmasq(dns服务和dhcp服务). 1.安装以上两个软件: 1 2 apt-get install hostapd apt-get install…

【Windows】git多帐号配置

【Windows】git多帐号配置 📔 千寻简笔记介绍 千寻简笔记已开源,Gitee与GitHub搜索chihiro-notes,包含笔记源文件.md,以及PDF版本方便阅读,且是用了精美主题,阅读体验更佳,如果文章对你有帮助…

【Java笔试强训 20】

🎉🎉🎉点进来你就是我的人了博主主页:🙈🙈🙈戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔🤺🤺🤺 目录 一、选择题 二、编程题 🔥字符串反…

Java中的异常是什么?

Java中的异常是指在程序运行时发生的错误或异常情况。这些异常可能会导致程序崩溃或无法正确执行,因此需要在代码中进行处理。Java中的异常机制可以帮助程序员捕获并处理异常,从而保证程序的稳定性和可靠性。 Java中的异常分为两种类型:受检…

linux中使用docker部署微服务

目录 一、制作jar包(如果看一眼很简单,可以直接使用结尾的jar) 1.首先创建一个微服务 demo2 2.启动微服务(在DemoApplication上右键执行启动就行) 注意:其他操作导致的 可能遇到的报错 3.修改端口 4.新…

【Docker】镜像与docker数据卷

文章目录 一、镜像1、镜像2、镜像原理之联合文件系统3、镜像原理之分层4、commit镜像 二、数据卷1、数据卷2、-v使用数据卷3、实战:MySQL 同步数据4、docker volume相关指令5、匿名和具名挂载6、数据卷之Dockerfile7、数据卷容器 一、镜像 1、镜像 镜像是一种轻量级…