HashMap底层存储分析

HashMap的底层原理分析

  1. 关键成员变量/常量:
  1. Node<k,v>[] table:HashMap底层存储数组
  2. Float loadfactor :加载因子,无参初始化时为默认加载因子
  3. Int threshold:扩容阈值,一般为table数组的长度*加载因子(0.75)
  4. Int Size:集合的长度(kv键值对的个数)
  5.  final int DEFAULT_INITIAL_CAPACITY = 1 << 4; 默认数组长度16
  6. final int MAXIMUM_CAPACITY = 1 << 30;最大数组长度
  7. final float DEFAULT_LOAD_FACTOR = 0.75f;默认加载因子
  8. final int TREEIFY_THRESHOLD = 8;转树形时链表的最小长度
  9. final int MIN_TREEIFY_CAPACITY = 64;转树形时数组的最小长度
  1. put元素时底层原理:
  1. 通过扰动函数计算所存放元素中key的hash值

    

  1. 添加元素前判断之前的数组table是否为空,如果是,则进行扩容

具体扩容原理如下:

扩容后:table数组长度由开始的0,变成16,扩容阈值从0变成了12

  1. 通过table数组长度-1&hash的方法,确定要添加元素所存放的位置,并判断此位置是否已有元素,如果没有则可直接存放

   

  1. 如果此位置已经有元素,通过hash和equals判断要添加元素的key值和已经在此位置元素的key值是否相同,如果key值不同,则对原位置元素的value进行覆盖
  1. 如果key值相同,则说明发生了hash冲突,此时将要添加的元素以node节点的形式连到原位置元素的后面,先判断是否为树形节点,如果不是则按单向链表的形式进行连接
  1. 后续添加元素,如果仍然在此位置发生哈希冲突,就继续往最后添加的元素后面连接,用p.next==null判断,在此过程中重复(4)的过此,即判断后续添加的元素与前面的元素的key值是否相同,相同则覆盖原元素的value,不相同则进行连接
  2. 如果同一个位置的连接的元素超过8个,同时table数组的长度小于64,则需进行扩容,当同一个位置的连接的元素超过8个同时数组长度超过64,则改为红黑树的形式连接要添加的元素

此时的扩容机制为数组长度按两倍扩容,扩容阈值也按两倍扩容

  1. 还有一种情况也需要扩容,即数组中的元素个数大于扩容阈值,此时会进行扩容

  

此时的扩容机制和上面相同,即数组长度和扩容阈值都按两倍扩容!

总结: hashmap集合put元素时的底层原理:
(1) 使用hash计算元素存储到数组的位置i=(数组长度-1)%hash,如果此处没有位置,则直接存储
(2) 如果此处有元素,判断key地址或内容是否相同,如果是则覆盖原元素中的value值
(3) 如果key不同则说明发生了hash冲突,此时元素已node节点形式连接到原位置元素的后面,先判断是否为树形,如果是,则按照树形结构添加,如果不是则按照单向链表添加,已p==null作为判断,将新增元素添加到链表末尾

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猿究院-赵文瑜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值