HashMap的底层原理

HashMap是一种键值存储结构,利用哈希函数解决哈希冲突,JDK1.7采用数组+链表,JDK1.8引入红黑树以优化长链表的查询性能。当链表长度超过8且总元素超过64时,HashMap会将链表转换为红黑树。加载因子和阈值影响HashMap的扩容,初始化容量为16,超过0.75负载因子会扩容。HashMap在多线程环境下不安全,可能导致死循环、元素丢失或值被覆盖。
摘要由CSDN通过智能技术生成

HashMap

刨析HashMap—>往祖坟上刨的那种!

扩展:

什么是哈希冲突:

先介绍哈希表:键 :值 存储结构,通过key查找值(貌似是字典)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZPMS3vjq-1678839478547)(D:\前锋学习笔记\笔记\屏幕截图 2023-03-14 204514.png)]

AB和BA 的地址发生的相同(碰撞情况),有两种方法解决,开放寻址,拉链法

拉链法:把AB放入以后,再放入BA发现有碰撞,就让存储AB的空间再存储个BA的地址空间,依次内推,直到不碰撞为止。

JDK1.7由 数组+链表(解决哈希冲突)

JDK1.8 数组+链表+红黑树

实现介绍一下(数组:有序-连续的)(链表:无顺序通过指针连接)(红黑树)的特点:

一:查询

​ (1):数组是按下标查询的,查询比较快。

​ (2):链表是从第一个的元素查找,直到查到需要的元素。

​ (3):平衡二叉树的遍历

二:插入

​ (1):数组的长度是先固定好的,需要移动其他元素。

​ (2):链表是可以动态的增减

​ (3):左旋右旋(保存平衡)

Hash的特点

又叫散列;具备数组的快速查询特点,又有链表的增加删除的元素的特点。

结合了数组和链表的优点。

JDK1.8为什么要添加上红黑树

数组和链表已经很方便了为什么?还要加上红黑树呢?是什么原因导致要加入红黑树?

答:上面扩展中提到了,解决碰撞的办法在链表上添加,但是当链表的长度过长时效率又低了,为了解决这个问题,当链表过长时,会让链表转为红黑树。

转换的条件先判断(链表超过8,并总量超过64)

为什么要按照数组,链表,红黑树这个顺序存储数据?

因为数组读写速度快,但是插入和删除时间复杂度大 还会产生碰撞,就替换成链表发挥他的插入和删除的优点,但是链表过长也会影响速度,这时候就用红黑树啦解决这个问题了。

如果直接使用红黑树的话增加新的节点和变色,左旋,右旋,保持平衡等操作直接就把增加新的节点速度变慢了。元素多的时候还不是太明显,一旦元素少的话,就相对比较下太慢了。

总结:后一个的数据结构是为了解决前一个数据结构在最坏情况(场景)下的最优处理方法。

加载因子和阈值

初始化是16

阈值是0.75

容量超过负载因子后,16*0.75 = ,会扩大为原来的两倍。

当然可以修改,一般不建议,除非是特殊的空间结构情况下。

// jdk1.8
static final int hash(Object key) {   
  int h;
  return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
 /* 
  h = key.hashCode() 为第一步:取hashCode值
  h ^ (h >>> 16)  为第二步:高位参与运算
 */
}

为什么线程不安全

多线程下扩容死循环。容易产生环形链表

多线程的put可能导致元素的丢失。可能导致值覆盖的情况

put和get并发时,可能导致get为null。

put 过程

  1. 首先根据 key 的值计算 hash 值,找到该元素在数组中存储的下标;
  2. 如果数组是空的,则调用 resize 进行初始化;
  3. 如果没有哈希冲突直接放在对应的数组下标里;
  4. 如果冲突了,且 key 已经存在,就覆盖掉 value;
  5. 如果冲突后,发现该节点是红黑树,就将这个节点挂在树上;
  6. 如果冲突后是链表,判断该链表是否大于 8 ,如果大于 8 并且数组容量小于 64,就进行扩容;如果链表节点大于 8 并且数组的容量大于 64,则将这个结构转换为红黑树;否则,链表插入键值对,若 key 存在,就覆盖掉 value。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二手Java程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值