HashMap

HashMap1.7数组+链表

1.8 数组+链表/红黑树

hashmap存放值的时候,经过2次hash计算,得到桶下标的位置,放入数组的下标位置

为什么要这么做呢,不能够直接放入?

因为在获取的时候,直接放入,查找的时候,需要遍历数组,直到找到这个值才行

而2次hash,就可以获取到桶下标的位置,根据下标的位置获取数据

为什么要2次hash呢?1次hash不行吗?

减少hash冲突,重复的可能性,让数据尽可能的分布均匀一点,让链表的长度尽可能减少

桶下标的计算

二次hash值%数组长度 的余数

为了减少链表的长度,有哪些办法?

1.扩容

2.红黑树

hashmap元素在数组长度超过3/4的时候,就会扩容?

通下标就会根据现有的数组长度 进行2次hash,那么桶下标就会随之改变

树化阈值 >8

数组容量>=64

为什么要用红黑树,为何不一上来就树化,树化的阈值为什么是8,何时会树化,何时会退化成链表?

使用红黑树就是为了解决链表过长的问题

如果链表过短的话,查询效率未必比红黑树差,而且内存占用上比红黑树少

根据泊松分布,一个桶中元素为8个点概率0.000006

在扩容的时候,树会进行拆分,树的元素小于等于6,会退化成链表

在移除时,移除前 检查,root根节点,root左子节点,root右子节点,root左子节点的左子节点,如果不存在,则退化成链表

索引如何计算?hashcode有了,hash方法?数组的容量为什么是2的N次幂?

先拿到元素的hashcode,然后在调用hash方法,最后&(数组的长度-1),得到桶下标的位置

二次hash是为了让数据分布的更加均匀一点,减少hash冲突,那么某个下标的链表长度就会更少

在2的n次幂的情况下, 二次hash值取模数组长度 = 2次hash值 &(数组的长度-1)

hashmap put的流程?1.7 1.8的不同?

hashmap 一开始会是一个空集合,在添加元素的时候,会创建一个16大小的集合

拿到key的hashcode,2次hash,&(数组长度-1)

如果桶下标已经存在数据,形成链表

当数组的长度达到64,并且链表的长度为8的时候,这个元素的链表才会进行升级成红黑树

为啥负载因子是0.75?

大于这个值,空间节省了,但是链表的长度可能就会更高

小于这个值,查询性能高了,但是空间浪费了

hashmap的key可以为null,必须实现hashcode和equals方法,key的对象不可变

hashmap每次扩容的大小

  • 初始容量为 16(默认),第一次扩容后容量变为 32
  • 每次都是2倍
相关推荐
Mahir087 小时前
Spring 循环依赖深度解密:从问题本质到三级缓存源码级解析
java·后端·spring·缓存·面试·循环依赖·三级缓存
RyFit8 小时前
SpringAI 常见问题及解决方案大全
java·ai
石山代码8 小时前
C++ 内存分区 堆区
java·开发语言·c++
绝知此事9 小时前
【算法突围 01】线性结构与哈希表:后端开发的收纳术
java·数据结构·算法·面试·jdk·散列表
无风听海9 小时前
C# 隐式转换深度解析
java·开发语言·c#
一只大袋鼠9 小时前
Git 进阶(二):分支管理、暂存栈、远程仓库与多人协作
java·开发语言·git
LuminousCPP10 小时前
数据结构 - 线性表第四篇:C 语言通讯录优化升级全记录(踩坑 + 思考)
c语言·开发语言·数据结构·经验分享·笔记·学习
德思特10 小时前
从 Dify 配置页理解 RAG 的重要参数
java·人工智能·llm·dify·rag
YOU OU10 小时前
Spring IoC&DI
java·数据库·spring
AI算法沐枫11 小时前
深度学习python代码处理科研测序数据
数据结构·人工智能·python·深度学习·决策树·机器学习·线性回归