当前位置: 首页 > article >正文

java中Map常见的面试问题,扩容问题,转红黑树的前提,解决Hash哈希冲突的方法

Map集合常见面试题

如何解决

解决哈希碰撞的方法
1链地址法(hashMap的处理方式)

        把hash表的每个单元作为链表的头节点。当发生冲突时放入到同一个hash值计算索引对应的链表。

2开放定址法

        发生冲突后寻找下一个地址

3再次hash法

        对hash值再次进行hash计算

4建立公共溢出区

        把hash表分为基本表和溢出表,当溢出时放入到溢出表;

问1:存储在Node中的hash值,是否就是key的hashCode()?

答:不是,存储在Node中的hash值是先对key进行hashCode()进行计算,然后再无符号右位移16,再按位异或的结果。

static final int hash(Object key) {

  int h;

  //hashCode和右移16进行按位异或运算

  return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);

}

问2:如何知道一个节点到底存储在Hash表(散列表)的哪个位置?

答:通过计算一个节点的key的hashCode()值(不是简单的进行hashCode),

(数组长度-1) & hash(hash%数组长度)计算的结果得出具体的下标,如果在索引位置只有一个节点直接返回,非一个节点继续在链表或红黑树中查找。

问3:什么时候需要把链表转为红黑树?

答:索引处链表的节点数大于8(从0开始的, 多以判断条件为 >=7), 数组的长度必须大于等于64,这个时候就会转成红黑树 要么就会数组的扩容。

问4:什么时候扩容?

答:情况一:

HashMap的Size(表中记录数)达到Hash中数组长度*loadFactor(扩容因子)时扩容。即比threshold大, 进行扩容。每次扩容为原数组长度的一倍(<< 1)

情况二:

Hash表中某个链表长度到达8,且Hash表中数组的长度小于64.

问5:Hash表中数组最大长度为多少?

答案:最大长度为 1<<30. 即:2的30次方法。

计算操作时,发现Hash表中数组长度为2的倍数效率最高,需要一直保持长度为2的倍数。数组长度最大取值为2的31次方减一。所以里面最大的2的倍数为2的30次方。

问6:Hash表中使用的是单向链表还是双向链表?数组扩容时, 链表使用的是尾加还是头加?

答1:单项链表

答2:JDK1.8及之后尾插法  JDK1.7及以前采用的是头插法;

问7:链表转为红黑树时,数组中是所有的链表都转为红黑树,还是什么情况?

答案:只有数组里某个下标中的节点个数>8, 并且数组长度>=64, 该下标中的链表转换为红黑树

问8:为什么java8中长度超过8以后将链表变为红黑树?

答案:红黑树的查询效率高于链表

问9:为什么选择8作为转换值?

答:元素个数为8的红黑树中,高度为:4.最多查找4次就能找到需要的的值,长度为8的链表,最多找7次。

例如长度为4就转换。红黑树高度为3,最多找3次。链表最多3次。

例如长度为7就转换。红黑树高度3,最多找3次。链表最多6次。多找3次和转换的性能消耗比较不值得。

在源码上可以看出,在理想状态下,受随机分布的 hashCode 影响,链表中的节点遵循泊松分布,而且根据统计,链表中节点数是 8 的概率已经接近千分之一,而且此时链表的性能已经很差了,所以在这种比较罕见和极端的情况下,才会把链表转变为红黑树

6.10总结:

  1. 从Java8开始HashMap底层由数组+链表+红黑树。
  2. 使用HashMap时,当使用无参构造方法实例化时,设置扩容因子为默认扩容因子(loadFactor)0.75。
  3. 当向HashMap添加内容时,会对Key做Hash计算,把得到的Hash值和数组长度-1按位与,计算出存储的位置。
  4. 如果数组中该索引没有内容, 直接存入数组中(Node节点对象), 该下标中有Node对象了, 把内容添加到对应的链表或红黑树中。
  5. 如果添加后链表长度大于等于8,会判断数组的长度是否大于等于64,如果小于64对数组扩容,扩容长度为原长度的2倍,扩容后把原Hash表内容重新放入到新的Hash表中。如果Hash长度大于等于64会把链表转换红黑树。
  6. 最终判断HashMap中元素个数是否已经达到扩容值(threshold),如果达到扩容值,需要进行扩容,扩容一倍。
  7. 反之,如果删除元素后,红黑树的元素个数小于等于6,由红黑树转换为链表。

http://www.kler.cn/a/108511.html

相关文章:

  • Linux系统常用操作与命令指南
  • 【mysql的当前读和快照读】
  • MyBatis——增删查改(XML 方式)
  • 【AI日记】24.11.14 复习和准备 RAG 项目 | JavaScript RAG Web Apps with LlamaIndex
  • Android Studio更新成2024.1.2版本后旧项目Gradle配置问题
  • flutter 发版的时候设置版本号
  • React-表单受控绑定和获取Dom元素
  • 基于群居蜘蛛算法的无人机航迹规划
  • 系统架构设计师-第16章-嵌入式系统架构设计理论与实践-软考学习笔记
  • 负载均衡的综合部署练习(hproxy+keepalived和lvs-DR+keepalived+nginx+Tomcat)
  • 漏洞复现-jquery-picture-cut 任意文件上传_(CVE-2018-9208)
  • windows8080端口占用
  • 更新电脑显卡驱动的操作方法有哪些?
  • Mac电脑配置Dart编程环境
  • YUV的红蓝颠倒(反色)的原因及解决
  • 通过Vue自带服务器实现Ajax请求跨域(vue-cli)
  • 【数据分析】上市公司半年报数据分析
  • ListenableFuture和countdownlatch使用example
  • mac 安装homebrew ,golang
  • 基于单片机16位智能抢答器设计
  • 圆锥面积 题解
  • 汇总下之RobotFramework自动化框架的系列文章
  • 计网强化
  • RSA ——Rational Structure Architecture r入门教程
  • 360智慧生活旗舰产品率先接入“360智脑”能力实现升级
  • AI:40-基于深度学习的森林火灾识别