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

Java面试-HashMap原理

一、二叉树相关:

  • 二叉树定义:每个节点有两个叉,包含左右子节点,不要求每个节点都有两个子节点,其左右子树也符合该特征。
  • 实现方式:可用数组或链表实现,用链表实现时,类TreeNode有value、left、right三个属性。
  • 分类:有满二叉树、完全二叉树、二叉搜索树、红黑树等,本次主要讲二叉搜索树和红黑树。
  • 二叉搜索树
    • 特点:又名BST树等,任意节点左边子树的值小于该节点,右边子树的值大于该节点,且左右子树也符合此特点。
    • 作用:支持快速查找、动态插入和删除数据。
    • 时间复杂度:平均情况下为O(log n),极端情况退化为链表时为O(n)。
  • 红黑树
    • 性质:节点要么红要么黑,根节点必为黑,叶子节点为黑色空节点,红色节点子节点为黑色,从任意节点到叶子节点所有路径包含相同数目黑色节点。
    • 作用:保证树的平衡,使时间复杂度稳定。
    • 时间复杂度:查找、添加、删除均为O(log n)。

二、散列表:

  • 基本概念:又名哈希表,根据键直接访问内存存储的值,由数组演化而来,利用数组按下标随机访问特性,时间复杂度为O(1)。
  • 散列函数:将键映射为数组下标的函数,要求计算的哈希值为大于等于0的正整数,相同键哈希值相同,不同键哈希值不同,但此条较难实现。
  • 散列冲突:多个键映射到同一数组下标位置,解决办法是拉链法,即数组下标对应链表,链表过长可改为红黑树,可提升效率、避免DOS攻击。
  • 操作时间复杂度:插入为O(1),平均查找和删除为O(1),大量冲突时链表查找和删除退化为O(n),改为红黑树后查找为O(log n)。

三、哈希map实现原理:

  • 底层结构:数组+链表+红黑树。
  • 数据存储:put元素时用key的哈希code重新计算哈希值定位数组下标,可能产生哈希冲突,key相同则覆盖value,不同则存入链表或红黑树(链表长度大于8且数组长度大于64时转红黑树)。
  • 数据获取:通过key的哈希值找到数组下标获取元素。
  • 版本区别:JDK 1.7采用数组+链表,JDK 1.8采用数组+链表+红黑树,链表长度大于8且数组长度大于等于64时转红黑树,扩容时红黑树节点小于等于6个退化为链表。

四、哈希map put方法流程:

  • 属性:默认容量为16,加载因子为0.75,阈值为容量乘以加载因子,table是存储数据的NODE数组,size是集合元素个数。
  • 流程:第一次添加先判断table是否为空,为空则调用resize初始化长度为16的数组,根据key计算索引,若索引处为空则添加数据,添加后判断size是否大于阈值,大于则扩容;非第一次添加,根据key计算索引,若索引处不为空,判断key是否存在,存在则覆盖value,判断是否为红黑树,是则走红黑树添加逻辑,否则遍历链表,key存在则覆盖,不存在则在尾部添加节点,链表长度大于等于8则转红黑树。

五、哈希map扩容机制:

  • 触发条件:添加元素或初始化时调用resize方法,第一次添加初始化长度为16的数组,数组元素超过阈值(数组长度乘以0.75)时扩容。
  • 扩容方式:容量变为原来的两倍,创建新数组,将旧数组数据挪到新数组,有三种情况,无冲突节点取哈希值模新数组长度定位下标,红黑树走红黑树添加逻辑,链表遍历拆分,节点哈希值按位与老容量等于0则留在原下标,不等于0则存到原下标加老容量的位置。

六、哈希map寻址算法:

  • 哈希值计算:调用key的hashCode方法得到哈希值,右移16位后与原哈希值做异或运算,使哈希值更均匀,减少冲突。
  • 索引计算:用数组长度减1按位与哈希值代替取模,性能更好,数组长度必须是2的n次幂,这样计算索引和扩容时重新计算索引效率更高。

七、哈希map 1.7多线程死循环问题:

  • 底层结构:数组+链表,扩容时链表迁移采用头插法。
  • 死循环原因:多线程下,一个线程先完成扩容使链表顺序颠倒,另一个线程迁移时可能导致节点相互指向,产生死循环。
  • 解决办法:JDK 1.8采用尾插法避免死循环。

文章转载自:

http://6cQRtdGv.cnfxr.cn
http://jUW5To4X.cnfxr.cn
http://3mg1w4C9.cnfxr.cn
http://h1ABdBCR.cnfxr.cn
http://FdCXVzIo.cnfxr.cn
http://hJGIHXd1.cnfxr.cn
http://AbxeQAsr.cnfxr.cn
http://eXPGWnYs.cnfxr.cn
http://nogPO3Cg.cnfxr.cn
http://owY1AniW.cnfxr.cn
http://6sbx9URk.cnfxr.cn
http://vsbu1hBA.cnfxr.cn
http://O6z35lFU.cnfxr.cn
http://90UeKalY.cnfxr.cn
http://YzsRwLrJ.cnfxr.cn
http://BuKilyoy.cnfxr.cn
http://nH3J21ox.cnfxr.cn
http://ZMyX6mxk.cnfxr.cn
http://50a3z3mJ.cnfxr.cn
http://DMFsbxbB.cnfxr.cn
http://5dHUIdKg.cnfxr.cn
http://RKRwIh6H.cnfxr.cn
http://iefddSnk.cnfxr.cn
http://pYqvABxX.cnfxr.cn
http://ZcCr0KF9.cnfxr.cn
http://kk0f8dxg.cnfxr.cn
http://7OXDzGIf.cnfxr.cn
http://ZWJUyF56.cnfxr.cn
http://CVlJvgtd.cnfxr.cn
http://IhDAuUk2.cnfxr.cn
http://www.dtcms.com/a/366906.html

相关文章:

  • 开关电源——只需这三个阶段,从电源小白到维修大神
  • Pydantic模型验证测试:你的API数据真的安全吗?
  • Linux高手才知道的C++高性能I/O秘诀:Vector I/O与DMA深度解析
  • DRMOS电源
  • 经典资金安全案例分享:支付系统开发的血泪教训
  • 手机秒变全栈IDE:Claude Code UI的深度体验
  • Go 自建库的使用教程与测试
  • 生活在数字世界:一份人人都能看懂的网络安全生存指南
  • 【gemini】2.5 Flash费用估算
  • DirectX修复必备指南:解决DLL缺失与游戏崩溃的5种方法
  • 如何建立一套切实可行的绩效考核体系:参考这三个前提、五大步骤、三个案例
  • 火山引擎数据智能体DataAgent总结分享
  • 基于51单片机智能大棚浇花花盆浇水灌溉补光散热设计
  • 深度学习-----修改学习率来优化模型的几个方法
  • 第4章 用户界面与基本操作
  • 从课前到课后,地理创新实验室赋能教学新范式
  • 焊接自动化测试平台图像处理分析-模型训练推理
  • Kafka面试精讲 Day 7:消息序列化与压缩策略
  • 【图像处理基石】如何在频域对图像进行处理和增强?
  • 探索 PostgreSQL 和 MySQL 之间的主要差异和相似之处,找到满足您项目需求的最佳数据库解决方案。
  • Python爬虫常用框架
  • HTTP与HTTPS杂谈-HTTPS防御了什么
  • Caffeine 双端队列优化揭秘:如何优雅维护访问和写入顺序
  • 02-ideal2025 Ultimate版安装教程
  • 代码随想录刷题Day49
  • 随时随地写代码:Jupyter Notebook+cpolar让远程开发像在本地一样流畅
  • 51单片机:中断、定时器与PWM整合手册
  • spring.profiles.active配置的作用
  • 设计模式六大原则2-里氏替换原则
  • 短视频运营为什么需要代理 IP