ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

HashMap的一些底层知识点

2022-08-14 15:00:08  阅读:168  来源: 互联网

标签:知识点 负载 HashMap 链表 键值 数组 table 底层


  • HashMap的底层数据结构?

数字+链表+红黑树

  • HashMap的存取原理?

    ①.判断键值对数组table[i]是否为空或为null,否则执行resize()进行扩容;

    ②.根据键值key计算hash值得到插入的数组索引i,如果table[i]==null,直接新建节点添加,转向⑥,如果table[i]不为空,转向③;

    ③.判断table[i]的首个元素是否和key一样,如果相同直接覆盖value,否则转向④,这里的相同指的是hashCode以及equals;

    ④.判断table[i] 是否为treeNode,即table[i] 是否是红黑树,如果是红黑树,则直接在树中插入键值对,否则转向⑤;

    ⑤.遍历table[i],判断链表长度是否大于8,大于8的话把链表转换为红黑树,在红黑树中执行插入操作,否则进行链表的插入操作;遍历过程中若发现key已经存在直接覆盖value即可;

    ⑥.插入成功后,判断实际存在的键值对数量size是否超多了最大容量threshold,如果超过,进行扩容。

  • 为啥会线程不安全?

    1.7中在并发的多线程使用场景中使用HashMap可能造成死循环。1.8中put/get方法都没有加同步锁,多线程情况最容易出现的就是:无法保证上一秒put的值,下一秒get的时候还是原值,所以线程安全还是无法保证。

  • 默认初始化大小是多少?为啥是这么多?为啥大小都是2的幂?

初始化大小是16,当你调用它的空构造器时

  • HashMap的扩容方式?负载因子是多少?为什是这么多?

1.7中:首先会创建一个新的entry数组,大小为原来的两倍,然后将重新对旧数组的每个元素的位置,进行添加,遇到哈希碰撞将使用头插法。1.8中:将不在对每个元素重新计算hash的值只需要看看原来的hash值新增的那个bit是1还是0就好了,是0的话索引没变,是1的话索引变成“原索引+oldCap”。同时它也变成了尾插法

负载因子0.75。

threshold就是在此Load factor和length(数组长度)对应下允许的最大元素数目,超过这个数目就重新resize(扩容),扩容后的HashMap容量是之前容量的两倍。默认的负载因子0.75是对空间和时间效率的一个平衡选择,建议大家不要修改,除非在时间和空间比较特殊的情况下,如果内存空间很多而又对时间效率要求很高,可以降低负载因子Load factor的值;相反,如果内存空间紧张而对时间效率要求不高,可以增加负载因子loadFactor的值,这个值可以大于1。

  • HashMap的主要参数都有哪些?
transient Node<K,V>[] table; //存储键值对的数列
transient int size //键值对的数量
int threshold; //数组扩容的临界值
final float loadFactor; //负载因子
  • hash的计算规则?

    先算出key的hashcode,然后用此hashcode与(hashcode >>> 16)相与也就是和它的高16位做与运算,最后再对table的长度进行取模。

可以看看美团技术团队的这篇文章https://zhuanlan.zhihu.com/p/21673805

标签:知识点,负载,HashMap,链表,键值,数组,table,底层
来源: https://www.cnblogs.com/xiaoovo/p/16585456.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有