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。

相关内容

热门资讯

华兴银行挺近五千亿,曝营利双降... 来源:密探财经(ID:Spy Finance)日前,定位于“立足湾区且进取心强劲”的广东华兴银行对外...
*ST荣控摘帽关键期收双重监管... 5月15日晚间,*ST荣控(000668.SZ)同步披露两则监管动态,公司及四名核心高管收到青岛证监...
200人砸6000亿美元,超级... 老鼠最多只能活3年,而鼹鼠轻轻松松活到30岁,背后差距从何而来?据财经媒体《36氪》刊文,谷歌的两位...
美股存储芯片股全线杀跌,英特尔... 记者|林芊蔚 吴斌编辑|江佩霞北京时间5月16日,美股三大指数均收跌超1%,纳指跌1.54%,终结周...
特朗普称美伊停火系“应其他国家...   新华社华盛顿5月15日电 美国总统特朗普15日在总统专机“空军一号”上接受采访时称,他本不赞成美...