HashMpa集合的底层存储原理

1.关键变量/常量

2.初始化方式

3.存储形式及原理

4.扩容机制

关键变量/常量:

Node<k,v>[] table:HashMap底层存储数组

Float loadfactor :加载因子,无参初始化时为默认加载因子

Int threshold:扩容阈值,一般为table数组的长度*加载因子(0.75)

Int Size:集合的长度(kv键值对的个数)

 final int DEFAULT_INITIAL_CAPACITY = 1 << 4; 默认数组长度16

final int MAXIMUM_CAPACITY = 1 << 30;最大数组长度

final float DEFAULT_LOAD_FACTOR = 0.75f;默认加载因子

final int TREEIFY_THRESHOLD = 8;转树形时链表的最小长度

final int MIN_TREEIFY_CAPACITY = 64;转树形时table数组的最小长度

初始化的方式:

    无参构造初始化:  通过此构造方法,将加载因子初始化为默认加载因子(0.75f),数组长度和扩容阈值未初始化,此时均为0.

   单参构造初始化:通过此构造方法,给定了数组的长度,并调用双参的构造方法,对成员变量进行初始化

       双参构造初始化:通过此构造方法传入的两个参数,对数组长度和加载因子及扩容阈值同时进行了初始化。

存储形式及存储原理:

存储形式:Node型数组+Node型单向链表+红黑树。
存储原理:以无参构造创建对象为例:

首先通过扰动函数计算所存放元素中key的hash值:

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

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

          如果此位置已经有元素,通过hash和equals判断要添加元素的key值和已经在此位置元素的key值是否相同,如果key值不同,则对原位置元素的value进行覆盖

         如果key值相同,则说明此时发生了hash冲突,此时将要添加的元素以node节点的形式连到原位置元素的后面,先判断是否为树形节点,如果不是则按单向链表的形式进行连接

      后续添加元素,如果仍然在此位置发生哈希冲突,就继续往链表最后添加的元素后面连接,用p.next==null判断,在此过程中重复上面的过程,即判断后续添加的元素与前面的元素的key值是否相同,相同则覆盖原元素的value,不相同则继续进行连接

 

            如果同一个位置的连接的元素超过8个(链表长度大于8),同时table数组的长度小于64,则需进行扩容,当同一个位置的连接的元素超过8个同时数组长度超过64,则改为红黑树的形式连接要添加的元素

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

扩容机制:(以无参构造创建对象)

HashMap集合添加元素时共有三种情况下会扩容:

首先是首次添加元素,此时扩容机制为,数组长度从0扩容为16,扩容阈值从0扩容为12

其次是同一个位置的连接的元素超过8个(链表长度大于8),同时table数组的长度小于64,则需进行扩容,此时扩容机制是数组长度和扩容阈值都扩容为原来的2倍

另外·当数组中元素超过其扩容阈值时,也会进行扩容,此时扩容机制和上一步的相同(数组长度和扩容阈值按之前的两倍扩容)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值