HashMap记录

HashMap的put方法首先检查数组table,若为空则初始化。对于非空key,计算哈希值并确定插入位置。如果桶为空,插入新Entry;否则,可能替换已有值或追加到链表。当元素数量超过负载因子(默认0.75)时,HashMap会扩容,创建新数组并重新分配所有Entry。链表长度超过8时,可能转换为红黑树。get方法通过哈希值查找键值对,返回匹配的值或null。
摘要由CSDN通过智能技术生成

put方法逻辑:

  • 如果 HashMap 的数组 table 为 null,则根据当前容量计算数组大小,创建一个新的数组。
  • 如果 key 为 null,则新建一个 Entry 对象,并将其插入到 table[0] 中(链表的头部)。
  • 如果 key 不为 null,则通过 hash(key.hashCode()) 方法计算出该键的哈希值 h,然后通过 h & (table.length - 1) 计算出该键应该存储在哪个桶中。如果该桶为空,则新建一个 Entry 对象,并将其插入到该桶中;否则,遍历该桶中的链表,查找是否已经存在相同的键。如果存在,则用新的值替换旧的值;否则,新建一个 Entry 对象,并将其插入到链表的末尾。
  • 如果当前 HashMap 中的元素数量超过了负载因子(默认为 0.75),则需要进行扩容。扩容时,将数组大小增加一倍,并将原有的所有 Entry 对象重新分配到新的桶中。

扩容逻辑:

  1. 创建一个新的 Entry 数组 table2,并将其大小设置为原来的两倍。
  2. 将原来的所有 Entry 对象重新分配到 table2 中。具体来说,遍历原来的数组 table 中的每个非空桶,将其中的每个 Entry 对象重新计算哈希值和目标桶的位置,并插入到 table2 对应的桶中。如果一些 Entry 对象经过重新计算哈希值后仍然位于原有的桶内,则将它们添加到该桶的链表末尾。
  3. 令 table 引用 table2。这样,HashMap 就开始使用新的哈希表了。
  4. 如果需要的话,调整阈值 threshold 的大小。

扩容时机:

  • 如果新添加的键值对后,元素数量已经超过了阈值0.75,则需要进行乘2扩容。
  • 调用 resize() 方法将哈希表大小增加一倍。

链表什么时候转换成红黑树:

  • 首先判断长度是否大于64且链表长度是否大于8,如果是则转换,如果小于长度64则进行扩容
  • 如果桶中第一个节点就是链表的头结点,遍历整个链表,并将每个节点替换为红黑树上的节点。
  • 如果转化后的红黑树仅有一个节点,则将其恢复为链表。

Get方法实现逻辑:

  • 如果数组 table 为空,则直接返回 null。
  • 如果 key 为 null,则返回 table[0] 中的值(链表的头结点),如果 table[0] 为空,则返回 null。
  • 否则,计算键的哈希值和桶的下标,并遍历该桶中的链表。如果找到相同的键,则返回对应的值;否则,返回 null。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值