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

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

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

  1. HashMap 的底层是个 Node 数组(Node<K,V>[] table),在数组的具体索引位置,如果存在多个节点,则可能是以链表或红黑树的形式存在。
  2. 增加、删除、查找键值对时,定位到哈希桶数组的位置是很关键的一步,源码中是通过下面3个操作来完成这一步:1)拿到 key 的 hashCode 值;2)将 hashCode 的高位参与运算,重新计算 hash 值;3)将计算出来的 hash 值与 “table.length - 1” 进行 & 运算。
  3. HashMap 的默认初始容量(capacity)是 16,capacity 必须为 2 的幂次方;默认负载因子(load factor)是 0.75;实际能存放的节点个数(threshold,即触发扩容的阈值)= capacity * load factor。
  4. HashMap 在触发扩容后,阈值会变为原来的 2 倍,并且会对所有节点进行重 hash 分布,重 hash 分布后节点的新分布位置只可能有两个:“原索引位置” 或 “原索引+oldCap位置”。例如 capacity 为16,索引位置 5 的节点扩容后,只可能分布在新表 “索引位置5” 和 “索引位置21(5+16)”。
  5. 导致 HashMap 扩容后,同一个索引位置的节点重 hash 最多分布在两个位置的根本原因是:1)table的长度始终为 2 的 n 次方;2)索引位置的计算方法为 “(table.length - 1) & hash”。HashMap 扩容是一个比较耗时的操作,定义 HashMap 时尽量给个接近的初始容量值。
  6. HashMap 有 threshold 属性和 loadFactor 属性,但是没有 capacity 属性。初始化时,如果传了初始化容量值,该值是存在 threshold 变量,并且 Node 数组是在第一次 put 时才会进行初始化,初始化时会将此时的 threshold 值作为新表的 capacity 值,然后用 capacity 和 loadFactor 计算新表的真正 threshold 值。
  7. 当同一个索引位置的节点在增加后达到 9 个时,并且此时数组的长度大于等于 64,则会触发链表节点(Node)转红黑树节点(TreeNode),转成红黑树节点后,其实链表的结构还存在,通过 next 属性维持。链表节点转红黑树节点的具体方法为源码中的 treeifyBin 方法。而如果数组长度小于64,则不会触发链表转红黑树,而是会进行扩容。
  8. 当同一个索引位置的节点在移除后达到 6 个时,并且该索引位置的节点为红黑树节点,会触发红黑树节点转链表节点。红黑树节点转链表节点的具体方法为源码中的 untreeify 方法。
  9. HashMap 在 JDK 1.8 之后不再有死循环的问题,JDK 1.8 之前存在死循环的根本原因是在扩容后同一索引位置的节点顺序会反掉。
  10. HashMap 是非线程安全的,在并发场景下使用 ConcurrentHashMap 来代替。


目录
相关文章
|
3天前
|
Java
【JDK 源码分析】HashMap 操作方法
【1月更文挑战第27天】【JDK 源码分析】HashMap Put 元素 初始化
|
7月前
|
设计模式 算法 Java
面试官:JDK1.8 HashMap扩容rehash算法是如何优化的?
本文跟大家聊一聊一个常见的面试题,那就是JDK1.8 HashMap扩容rehash算法是如何优化的?
|
3天前
|
安全 Java
【JDK 源码分析】HashMap 线程安全问题分析
【1月更文挑战第27天】【JDK 源码分析】HashMap 线程安全问题分析
|
3天前
|
存储 Java
【JDK 源码分析】HashMap 底层结构
【1月更文挑战第27天】【JDK 源码分析】HashMap 底层结构
|
3天前
|
存储 安全 Java
Hashtable和HashMap:差异,数据结构概述,以及JDK的影响
Hashtable和HashMap:差异,数据结构概述,以及JDK的影响
26 0
|
10月前
|
存储 算法 安全
高频面试题-JDK源码篇(HashMap)
我觉得HashMap是一个高频面试题,甚至被问烂了,如果你还不懂HashMap原理,你很幸运,看了这边文章之后你将不存在这个问题!这里整理了一下HahsMap可能会被问到的知识点,从源码的角度去做了一些分析,当然你可以试着自己先回答一下: HashMap底层用到了那些数据结构? 为什么要用到链表结构? 为什么要用到红黑树? HashMap如何扩容的? HashMap是如何Put一个元素的? HashMap是如何Get一个元素的? 什么是Hash冲突 还有哪些解决Hash冲突的方式?
52 0
|
10月前
|
安全 算法 Java
JDK 7 HashMap 并发死链
JDK 7 HashMap 并发死链
|
11月前
|
存储 安全 算法
HashMap为什么在多线程操作下不安全(jdk1.7和jdk1.8原因不同)
HashMap为什么在多线程操作下不安全(jdk1.7和jdk1.8原因不同)
73 0
|
12月前
|
Java
【JavaP6大纲】Java基础篇:为什么jdk8以后HashMap会使用红黑树优化?
【JavaP6大纲】Java基础篇:为什么jdk8以后HashMap会使用红黑树优化?
|
存储 缓存 Java
2022 最新 JDK 17 HashMap 源码解读 (一)
2022 最新 JDK 17 HashMap 源码解读 (一)
292 0