超级实习生计划打卡—HashMap的实现原理(简要概述)

2023-10-29

HashMap简介
数据无序、底层由数组+链表+红黑树实现(JDK8开始)、容量是2的指数幂、初始大小为16(不指定长度)


发生冲突时通过拉链法处理,当链表大于阈值时(阈值默认为8),将链表转化为红黑树
时间复杂度:哈希查找O(1),哈希冲突多O(n),红黑树O(log n),平均O(1)
HashMap里面设计的算法(put和get操作原理)


主要涉及哈希算法和寻址算法。哈希算法是在put过程中,根据传入key值获取对应hash值的一种方法;寻址算法在put和get过程中都有所运用,即根据hash值获得下标位置的方法。
哈希算法


根据一个key,通过计算得到它对应的hash值(即将hash code向右移16位,再与原数值进行异或运算)(每个虚拟机对hash的计算都不一样,有些跟地址有关)


  • 直接使用hashcode做hash指的话,通过寻址算法所得结果有许多相同
  • 通过哈希算法的优化,一定程度避免了hash冲突,让数据更加散列

寻址算法
根据hash值计算数组下标位置
一个key的hash值,用这个hash值跟数组长度取模,就可以得到下标位置, 实际在源码中,采用了与运算代( 两个都是1,结果为1;不然是0 )替了取模(因为对于现代的处理器来说,除法和求余数(模运算)是最慢的动作)
公式:(n - 1) & hash(n为数组长度)
 

put和get操作过程详解
put过程
根据哈希算法获取哈希值
哈希数组为空,则创建数组,默认初始大小为16
对哈希值进行寻址运算,获取在数组中应该存入的下标位置,此时分为四种情况
如果该下标位置为空,则直接存入key,value键值对
如果不为空,只有一个元素且key相等,满足相等条件,替换旧值,不相等则拉链处理
如果该位置存了一个TreeNode,则说明是红黑树,执行树的插入操作
如果是一个链表,则遍历链表,如果中途有相等则替换,否则将key,value键值对插入链表最后;如果链表长度大于阈值 ,则转化为红黑树
get过程
通过寻址算法找到key值应该对应的下标
如果节点为空则返回空
再判断首节点.key 是否和目标值相同, 相同则直接返回(首节点不用区分链表还是红黑树)
首节点.next为空, 则直接返回空
首节点是树形节点, 则进入红黑树数的取值流程, 并返回结果
进入链表的取值流程, 并返回结果
HashMap的容量大小
如详解里面所提到的,HashMap的容量大小一般为2的指数次幂,在未指定初始大小的时候的默认大小为16,其原因有以下几点

当n为2的指数幂时,根据寻址算法中的计算公式,n减1后换算成2进制,则每一位都为1,与hash进行与运算,就可 以得到(0~n-1)范围内的每一个index
当n不为2的指数次幂时,减1后换算成2进制,会出现0,与hash进行与运算,会导致 (0~n-1)范围内的某些index永远得不到
总结:当n不为2的指数幂时,有些地址永远得不到
加载因子和转化阈值
加载因子又名负载因子、装载因子

加载因子代表哈希表在其容量到达一定程度后,需要进行扩容

负载因子越大表示散列表的装填程度越高,反之愈小

负载因子越大, 对空间的利用更充分,但哈希碰撞机会变大,后果是查找效率的降低

负载因子太小,对空间造成严重浪费,但数据稀疏使碰撞机会变小,查询效率提高

加载因子0.75:根据泊松分布,加载因子为0.75时,节点出现在频率在Hash桶(表)中遵循参数平均为0.5的泊松分布。(源码没有解释,网上没统一答案)

转化阈值8:用0.75作为加载因子时,桶中元素到达8个的时候,概率已经变得非常小,超过8个是几乎不可能的
 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

超级实习生计划打卡—HashMap的实现原理(简要概述) 的相关文章

  • 【数据结构/C++】树和二叉树_二叉链表

    include
  • 牛客网(二叉树)

    这个题目和leetcode比起来就是有一些不一样 需要我们自己来写接口函数 所以有一些麻烦 我们得写一个中序遍历的函数做最后的输出 也得写一个函数来存储字符进去 还得写一个接口函数来创造节点 这个题目就和二叉树如何创造节点很相似 我们一个一
  • 二叉树(接口函数的实现)

    今天继续来分享的是二叉树 我们废话不多说 直接来看下面的几个接口函数 然后我们把他们实现 我们就掌握二叉树的二分之一 今天粉丝破千了 属实有点高兴了 typedef char BTDataType typedef struct Binary
  • 【C++】手撕string思路梳理

    目录 基本思路 代码实现 1 构建框架 2 构建函数重载 3 迭代器 4 遍历string 5 resetve 开空间 insert任意位置插入push back append 按顺序依次实现 6 erase删除 clear清除 resiz
  • 每日一练2023.12.17——大笨钟的心情【PTA】

    题目链接 L1 077 大笨钟的心情 题目要求 有网友问 未来还会有更多大笨钟题吗 笨钟回复说 看心情 本题就请你替大笨钟写一个程序 根据心情自动输出回答 输入格式 输入在一行中给出 24 个 0 100 区间内的整数 依次代表大笨钟在一天
  • 代码随想录算法训练营Day3 | 203.移除链表元素、707.设计链表、59.螺旋矩阵II

    LeetCode 203 移除链表元素 本题思路 就是常规的移除链表中的元素的操作 需要注意的点 头节点 head val val 的情况的处理 如果 head val val 就要继续往后 head head next 因此我们要遍历到第
  • LeetCode326. Power of Three

    文章目录 一 题目 二 题解 一 题目 Given an integer n return true if it is a power of three Otherwise return false An integer n is a po
  • 深度学习目标检测全连接层什么意思

    在深度学习目标检测中 通常我们使用卷积神经网络 Convolutional Neural Network CNN 进行特征提取 CNN 的主要结构包括卷积层和池化层 用于从输入图像中提取特征 然而 为了最终输出目标的类别和位置信息 通常在网
  • 力扣每日一题:162. 寻找峰值(2023-12-18)

    力扣每日一题 题目 162 寻找峰值 日期 2023 12 18 用时 10 m 9 s 时间 0 ms 内存 40 54 MB 代码 class Solution public int findPeakElement int nums i
  • 代码随想录算法训练营第42天| ● 01背包问题,你该了解这些! ● 01背包问题,你该了解这些! 滚动数组 ● 416. 分割等和子集

    416 分割等和子集 已解答 中等 相关标签 相关企业 给你一个 只包含正整数 的 非空 数组 nums 请你判断是否可以将这个数组分割成两个子集 使得两个子集的元素和相等 示例 1 输入 nums 1 5 11 5 输出 true 解释
  • 数组对象排序 (arr.sort())

    前端面试题库 面试必备 推荐 地址 前端面试题库 对象排序 arr sort 描述 方法sort 将在原数组上对 数组元素 进行排序 即排序时不创建新的数组副本 如果想按照别的顺序进行排序 就必须提供比较函数 该函数要比较两个值 然后返回一
  • 数据结构算法-快速排序

    核心思路 快速排序算法核心思路 选择一个 基准 元素 将数组分为两个子数组 一个包含比基准小的元素 另一个包含比基准大的元素 然后对这两个子数组进行递归排序 基准数 初始化两个索引 i 和 j 分别子数组的开头和结尾 初始化基准元素 bas
  • LeetCode 1901. 寻找峰值 II

    一 题目 1 题目描述 一个 2D 网格中的 峰值 是指那些 严格大于 其相邻格子 上 下 左 右 的元素 给你一个 从 0 开始编号 的 m x n 矩阵 mat 其中任意两个相邻格子的值都 不相同 找出 任意一个 峰值 mat i j
  • 数据结构学习笔记(七)搜索结构

    文章目录 1 前言 2 概念 3 静态搜索结构 3 1 静态搜索表 3 2 顺序搜索表 3 2 1 基于有序顺序表和顺序搜索和折半搜索 4 二叉搜索树
  • LeetCode 2397. 被列覆盖的最多行数,状态压缩优化回溯法

    一 题目 1 题目描述 给你一个下标从 0 开始 大小为 m x n 的二进制矩阵 matrix 另给你一个整数 numSelect 表示你必须从 matrix 中选择的 不同 列的数量 如果一行中所有的 1 都被你选中的列所覆盖 则认为这
  • 【每日一题】2397. 被列覆盖的最多行数-2024.1.4

    题目 2397 被列覆盖的最多行数 给你一个下标从 0 开始 大小为 m x n 的二进制矩阵 matrix 另给你一个整数 numSelect 表示你必须从 matrix 中选择的 不同 列的数量 如果一行中所有的 1 都被你选中的列所覆
  • 【LeetCode:114. 二叉树展开为链表 | 二叉树 + 递归】

    算法题 算法刷题专栏 面试必备算法 面试高频算法 越难的东西 越要努力坚持 因为它具有很高的价值 算法就是这样 作者简介 硕风和炜 CSDN Java领域新星创作者 保研 国家奖学金 高中学习JAVA 大学完善JAVA开发技术栈 面试刷题
  • 浅谈归并排序:合并 K 个升序链表的归并解法

    在面试中遇到了这道题 如何实现多个升序链表的合并 这是 LeetCode 上的一道原题 题目具体如下 用归并实现合并 K 个升序链表 LeetCode 23 合并K个升序链表 给你一个链表数组 每个链表都已经按升序排列 请你将所有链表合并到
  • 链表的中间节点

    链表的中间节点 力扣 LeetCode 官网 全球极客挚爱的技术成长平台 备战技术面试 力扣提供海量技术面试资源 帮助你高效提升编程技能 轻松拿下世界 IT 名企 Dream Offer https leetcode cn problems
  • 用栈实现队列(OJ中报错的处理)

    用栈实现队列 ERROR AddressSanitizer myQueueFree函数中栈的释放处现了问题 没有调用StackDestory而是直接free了 这个是栈初始化时 capacity与malloc申请的空间大小没有匹配 请你仅使

随机推荐