HashMap的底层原理
创始人
2025-05-28 08:21:08

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。

相关内容

热门资讯

今日重大通报“家乡大贰是不是有... 您好:家乡大贰这款游戏可以开挂,确实是有挂的,需要软件加微信【4194432】,很多玩家在家乡大贰这...
今日热点“ 杭州都莱 辅助挂透... 您好:杭州都莱这款游戏可以开挂,确实是有挂的,需要软件加微信【6617969】很多玩家在这款游戏中打...
〖重大通报〗“微乐龙江麻将怎么... 亲.微乐龙江麻将这款游戏是可以开挂的,确实是有挂的,通过添加客服【4579337】很多玩家在这款游戏...
<必备盘点>... 有 亲,根据资深记者爆料欢喜贵州是可以开挂的,确实有挂(咨询软件无需打开...
(独家揭秘)“人人乐麻将.到底... (独家揭秘)“人人乐麻将.到底有挂吗@确实真的有挂亲,人人乐麻将这个游戏其实有挂的,确实是有挂的,需...