HashMap

hashmao插入流程
数组+链表+红黑树,线程不安全

当表长小于64时,不转换为红黑树,数组长度翻倍扩容

当同一hash下元素小于8,不转换为红黑树

加载因子0.75,默认大小16.

  • putVal()函数:
条件操作
表是空表resize()初始化表
新元素没有与旧元素碰撞存入新元素
新元素与旧元素碰撞见下表
走的前两步的话就判断是否需要扩容resize()
条件操作
新元素与旧元素的key相同记录这个位置
旧元素已经是红黑树节点了在红黑树中插入新元素
新元素与旧元素key不同,且旧元素不是红黑树节点在链表尾部插入新元素,如果插入后元素达到8个时,如果原数组长度达到64,就转换为红黑树,否则resize()。在遍历到尾部的过程中如果遇到相同key的元素就记录这个位置并直接跳出这个循环
(此步用来处理键值对相同时是否替换为新元素的情况)记录的位置不空&&(允许修改||这个位置的值为空)记录新元素并返回旧元素
  • resize()函数:
条件操作
原表容量>0(正常扩容)没超过最大值就翻倍,否则设置为最大值
原表容量<=0且原阈值>0(初始化)新表容量为原阈值,新阈值为新容量*加载因子0.75或整数最大值
原表容量<=0原阈值<=0使用定义的默认值

然后将原表中的每一条链表分为两条,hash&旧容量为0的放在新表原位置,不为0的放在旧表容量+原位置

  • hash()函数:

    • (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16)【扰动函数】

    h>>>16: int为32位,>>>为无符号右移,取出该hash值的高16位

    ^: 异或,&更趋近于0,|更趋近于1,使用^可以更加随机

    使用hashcode与其高16位异或:

    ​ 由于绝大多数情况下length一般都小于2^16即小于65536。所以return h & (length-1);结果始终是h的低16位与(length-1)进行&运算。

    ​ 因此可以将hashcode的高16位也利用起来,使最终得到的结果更加散列。

    • indexFor(h & (length-1))(1.8中没有,但原理相同)

      • h为上一步hashcode计算后的值

      • length为数组长度

      对length取余

红黑树

红黑树插入

插入时:

  • 父节点为黑色:直接插入。
  • 父节点为红色:
    • 叔叔节点为红色:直接插入,将父节点和叔叔节点变黑,祖父变红,向根回溯,直到根并将其设置为黑
    • 叔叔节点为黑色:
      • 左左(右右):将父节点作为祖父节点,原祖父节点作为原父节点的右(左)孩子,原父节点的右(左)孩子作为原祖父节点的左(右)孩子,原祖父节点的右(左)孩子不变,然后原祖父变红,原父节点变黑。
      • 左右(右左):将当前节点作为父节点,原父节点作为当前节点的左(右)孩子,然后进行左左(右右)旋转。

删除:红黑树删除节点
个人理解:红黑树相当于变种的平衡二叉树,通过颜色来保证树的大致平衡。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值