欢迎光临
我们一直在努力

HashMap保存一个key-value键值对的过程

1. 根据key计算一个新的hash值:

  首先,当调用HashMap.put(key, value)方法时,HashMap首先会计算key的哈希值。根据key的哈希值,按位异或操作,将高16位与低16位混合,重新计算一个新的哈希值,类似牌桌上“洗牌打乱”的过程,令哈希值再次随机,减少哈希碰撞的概率。
2. 判断哈希表是否初始化:

  此时,判断哈希表是否已经初始化。如果没有初始化,会按照默认容量16进行初始化,加载因子为0.75。
3. 根据hash值,计算哈希表的下标:

  HashMap根据(n – 1) & hash,计算key应该存放在数组的哪个位置。
4. 根据下标,判断是否产生哈希冲突:

  为什么会产生哈希冲突?由于哈希表的容量有限,初始长度为8,容量为16,即有可能产生哈希冲突,可能出现两个元素下标一样的情况。以及,不同key也能计算出相同的哈希值;还有一种情况,即使hash值不同,但(n-1) & hash计算结果相同,也会计算出相同的哈希值。
5.无哈希冲突的情况:

  如果没有哈希冲突,直接创建一个新的Node节点并放入数组对应位置。
6. 如果产生哈希冲突,会遍历整条链表,判断key是否相同:

  当产生哈希冲突时,HashMap会遍历该位置上的链表,查找是否已存在相同的key,key相同有以下几个判断标准:1. hash值相等。2. 内存地址相同。3. equals()方法返回true。
7. 如果key相同,则覆盖value:

  如果找到了相同的key,此时hash值相同且key相等,则进行value替换,覆盖旧值。
8. 如果key不相同,则添加到链表尾部并检查长度与容量,判断是否树化:

  如果遍历完整个链表,都没有找到相同的key,则将新节点添加到链表尾部,插入尾结点。插入完成后,检查链表长度和容量。当链表长度≥8,数组容量<64时,会先进行扩容,减少哈希冲突,提高效率。直到数组容量≥64,链表的效率已然降低,此时会将哈希表树化为“红黑树”。红黑树的特点有自平衡,二分查找。这些可以有效提高效率,解决链表过长容量过大导致效率降低的问题。
9. 若产生哈希冲突,并且当前节点是红黑树节点,则将新Node节点加入红黑树:

  如果当前位置已经是红黑树结构,则调用红黑树的插入方法。此时保持红黑树的平衡特性,插入后可能需要进行旋转和重新着色。
10. 扩容检查与执行:

  最后,检查是否需要扩容。扩容阈值指的是:数组容量*加载因子,默认情况下:16 * 0.75 = 12。所以当元素数量超过12时,触发扩容。判断键值个数,是否超出“扩容阈值”,如果超出,则扩容。

赞(0)
未经允许不得转载:171主机测评 » HashMap保存一个key-value键值对的过程
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址