JDK常用的数据类型【1】 ——HashMap(分享篇)

news/2025/2/12 23:44:29/

在这里插入图片描述

x mod 2^n = x & (2^n - 1)

1. 拿到 key 的 hashCode 值
2. 将 hashCode 的高位参与运算,重新计算 hash 值
3. 将计算出来的 hash 值与 (table.length - 1) 进行 & 运算

数据结构

1.B树 和 B+树

  • B树叶子节点可以存放多个元素
  • B+树的叶子节点之间是有指针的

红黑树

  1. (1) 每个节点或者是黑色,或者是红色。
  2. (2) 根节点是黑色。
  3. (3) 每个叶子节点是黑色。 [注意:这里叶子节点,是指为空的叶子节点!]
  4. (4) 如果一个节点是红色的,则它的子节点必须是黑色的。
  5. (5) 从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。

HashMap 的底层是个 Node 数组(Node<K,V>[]
table),在数组的具体索引位置,如果存在多个节点,则可能是以链表或红黑树的形式存在。

增加、删除、查找键值对时,定位到哈希桶数组的位置是很关键的一步,源码中是通过下面3个操作来完成这一步:

  • 1)拿到 key 的 hashCode 值;
  • 2)将 hashCode 的高位参与运算,重新计算 hash 值;
  • 3)将计算出来的
    hash 值与 “table.length - 1” 进行 & 运算。
  • HashMap 的默认初始容量(capacity)是 16,capacity 必须为 2 的幂次方;默认负载因子(load factor)是 0.75;实际能存放的节点个数(threshold,即触发扩容的阈值)= capacity * load factor。

HashMap 在触发扩容后,阈值会变为原来的 2 倍,并且会对所有节点进行重 hash 分布,重 hash
分布后节点的新分布位置只可能有两个:“原索引位置” 或 “原索引+oldCap位置”。例如 capacity 为16,索引位置 5
的节点扩容后,只可能分布在新表 “索引位置5” 和 “索引位置21(5+16)”。

导致 HashMap 扩容后,同一个索引位置的节点重 hash 最多分布在两个位置的根本原因是:
1)table的长度始终为 2 的 n 次方;
2)索引位置的计算方法为 “(table.length - 1) & hash”。HashMap 扩容是一个比较耗时的操作,定义HashMap 时尽量给个接近的初始容量值。

  • HashMap 有 threshold 属性和 loadFactor 属性,但是没有 capacity 属性。初始化时,如果传了初始化容量值,该值是存在 threshold 变量,并且 Node 数组是在第一次 put
    时才会进行初始化,初始化时会将此时的 threshold 值作为新表的 capacity 值,然后用 capacity 和loadFactor 计算新表的真正 threshold 值。
  • 当同一个索引位置的节点在增加后达到 9 个时,并且此时数组的长度大于等于 64,则会触发链表节点(Node)转红黑树节点(TreeNode),转成红黑树节点后,其实链表的结构还存在,通过 next属性维持。链表节点转红黑树节点的具体方法为源码中的 treeifyBin方法。而如果数组长度小于64,则不会触发链表转红黑树,而是会进行扩容。
  • 当同一个索引位置的节点在移除后达到 6 个时,并且该索引位置的节点为红黑树节点,会触发红黑树节点转链表节点。红黑树节点转链表节点的具体方法为源码中的 untreeify 方法。
  • HashMap 在 JDK 1.8 之后不再有死循环的问题,JDK 1.8 之前存在死循环的根本原因是在扩容后同一索引位置的节点顺序会反掉。
  • HashMap 是非线程安全的,在并发场景下使用 ConcurrentHashMap 来代替。

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

相关文章

AndroidTV焦点问题总结

AndroidTV焦点问题总结 焦点1.确定当前焦点位置2.子view焦点跟随父View变化3.设置下一个获取焦点的View4.设置父View和子View哪个获取焦点5.常用的按键值7.控制RecycleView焦点跳转逻辑8.其他View焦点跳转到RecyclerView9.ViewGroup的某个子View获取焦点 焦点 1.确定当前焦点位…

Spring的存储与获取Bean

Spring的存储与获取Bean &#x1f50e;Spring—存储Bean配置扫描路径利用类注解进行存储添加注解存储Bean关于Id为什么需要五个类注解类注解之间的关系 利用方法注解进行存储关于Id &#x1f50e;Spring—获取Bean属性注入Set注入构造方法注入总结(Spring的注入方式? 它们之间…

运维圣经:Webshell应急响应指南

目录 Webshell简介 Webshell检测手段 Webshell应急响应指南 一. Webshell排查 二. 确定入侵时间 三. Web日志分析 四. 漏洞分析 五. 漏洞复现 六. 清除Webshell并修复漏洞 七. Webshell防御方法 Webshell简介 Webshell通常指以JSP、ASP、 PHP等网页脚本文件形式存在…

IM相关技术

messages表 保存的消息记录(Saved Messages) bff,session TON以及tdlib 官方版设置中文 tg://setlanguage?langclassic-zh-cn https://web.telegram.org/k/ https://web.telegram.org/a/ https://github.com/TGX-Android https://github.com/NekoX-Dev/NekoX, 内置公共代理不…

【第9题】容斥原理:P3197 [HNOI2008]越狱

题目&#xff1a;P3197 [HNOI2008]越狱 题目原文请移步下面的链接 https://www.luogu.com.cn/problem/P3197 参考题解&#xff1a;https://www.luogu.com.cn/problem/solution/P3197 标签&#xff1a;OI、 数学、容斥 题解 思路 第一点&#xff1a;排列组合的问题&#xf…

怎么快速给需要的网路标记颜色?

引入 我们在走线的时候&#xff0c;需要知道那些类型的线需要先走&#xff0c;接下来又要走那些类型的线&#xff0c;然后依次走完&#xff0c;如果在团队中&#xff0c;这一类型的线分配给这个人走&#xff0c;哪一类型的线有分配给那个人走。而在不管是那单个人&#xff0c;还…

单片机按键开机检测

POWER通过单片机的IO口控制&#xff0c;按键按下口单片机供电上电&#xff0c;单片机控制POWER引脚置高&#xff0c;维持自身供电。

MIT6.024学习笔记(三)——图论(2)

科学是使人变得勇敢的最好途径。——布鲁诺 文章目录 通信网络问题二叉树型直径路由器规模路由器数量拥挤程度 二维数组型直径路由器规模路由器数量拥挤程度 蝴蝶型直径路由器规模路由器数量拥挤程度 benes型直径路由器规模路由器数量拥挤 通信网络问题 在通信网络中&#xff…