春招面试题总结--hashmap的插入过程

HashMap 的插入过程

  • 若哈希表没有初始化,先进行初始化
  • 根据key 的值计算出该键值对在数组中的下标位置i
  • 判断table[i]是否为空,若为空,直接插入;
  • 若不为空,则判断当前的key 与 table[i] 保存的key 是否相同,若相同则直接覆盖;
  • 若不同,先判断当前的table[i]是不是红黑树,若是,就按照红黑树的插入算法进行插入
  • 若是链表结构,则遍历链表,使用equals() 方法判断key是否存在,若存在则直接覆盖。否则插入链表末尾

代码示例

HashMap<String,Integer> map = new HashMap<>();

map.put(null,10);

map.put("dd",20);

1、执行new HashMap<>() 之后,哈希表只做一件事情:将哈希表的装载因子赋值为默认的0.75

public HashMap() {
	this.loadFactor = DEFAULT_LOAD_FACTOR; // 初始化默认的加载因子
}

可以发现,此时并没有实际申请哈希表的内存,和 ArrayList 一样;

2、执行map.put(null,10);

第一次执行put时,首先会判断底层的数组是否被初始化,如果没有初始化,则先进性初始化。

若已经执行过初始化,则开始对 key 进行处理

if ((tab = table) == null || (n = tab.length) == 0) // table 就是哈希表底层的数组
	n = (tab = resize()).length;

3、处理 key

计算出 key = null 在数组内的下标

i = (n - 1) & hash = (16-1) & hash(null) = 0

得到该key在数组中的下标之后,首先判断 table[i] 是否为空,若为空则将(null,10)封装成一个 Node,放入 table[i] 中.

若table[i] 不为空,则会进行以下判断:

  • ​ 判断两个key 是否存在,若已经存在相同的key, 则直接覆盖。若不存在,进行下一步
  • ​ 判断是否为 treeNode,若是的话,直接将键值对插入红黑树
  • ​ 若不是 treeNode,开始遍历链表进行插入,若 key 已经存在,则直接覆盖;若不存在。将此键值对插入俩表末尾;若链表长度大于8,先转化为红黑树再插入;

第三句执行 map.put("dd",20); 时,首先也会判断table数组是否被初始化,显然第二步已经初始化了,所以直接对 key=dd 进行处理,计算得数组下标的位置为0**(null 和 dd 计算出的下标位置相同)**

4、最后更新哈希表中键值对的个数size; 若新的个数大于 threshold (threshold=capacity*loadFactor),则调用resize()函数进行扩容。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值