首页 > 编程语言 >hashMap源码分析

hashMap源码分析

时间:2024-04-12 09:33:50浏览次数:27  
标签:分析 hash hashMap 哈希 链表 源码 key null 节点

先分析hashMap的put方法:当执行put操作时会调用底层的putVal方法,以下是这个方法的分析

执行Put方法时会先判断当前哈希表是否为空,为空则先扩容,然后计算出hash值对应的索引,判断索引位置上的节点是否为空,空则插入这个新节点。否则便要判断节点上的key是不是和原先的key相同,相同则进行更新key操作,key不同的话便是出现哈希冲突了,这时便要看当前数据结构是红黑树还是链表了,链表和红黑树都有不同的对hash冲突的处理方法。

1. 红黑树处理哈希冲突的方式是通过在树中插入新的节点,并根据键的比较结果找到合适的位置进行插入

2. 链表处理哈希冲突的方式相对简单,当发生哈希冲突时,新节点会被插入到哈希表对应桶的链表的末尾。

 /**
     *它接收了四个参数:hash表示键的哈希值,key表示键,value表示值,onlyIfAbsent表示仅在键不存
     * 在时才插入。
     * @return 
     */
final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) {
    Node<K,V>[] tab; // 声明哈希表数组
    Node<K,V> p; // 声明节点
    int n, i; // 声明数组长度和索引变量
    if ((tab = table) == null || (n = tab.length) == 0) // 判断哈希表是否为空,如果为空则进行扩容
        n = (tab = resize()).length;
    if ((p = tab[i = (n - 1) & hash]) == null) // 根据哈希值计算索引,如果索引位置为空,则在该位置插入新节点
        tab[i] = newNode(hash, key, value, null);
    else {
        Node<K,V> e; // 声明临时节点
        K k; // 声明临时键
        if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) // 判断当前节点是否为要插入的键对应的节点
            e = p;
        else if (p instanceof TreeNode) // 如果当前节点为树节点,则调用树节点的插入方法
            e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
        else {
            // 遍历链表,直到找到对应的节点或者到达链表尾部
            for (int binCount = 0; ; ++binCount) {
                if ((e = p.next) == null) { // 如果下一个节点为空,则在链表尾部插入新节点
                    p.next = newNode(hash, key, value, null);
                    if (binCount >= TREEIFY_THRESHOLD - 1) // 如果链表长度超过树化阈值,则进行树化操作
                        treeifyBin(tab, hash);
                    break;
                }
                if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) // 判断当前节点是否为要插入的键对应的节点
                    break;
                p = e; // 更新当前节点为下一个节点
            }
        }
        if (e != null) { // 如果找到了对应的节点
            V oldValue = e.value; // 获取旧值
            if (!onlyIfAbsent || oldValue == null) // 如果不是仅在键不存在时插入,或者旧值为空,则更新值
                e.value = value;
            afterNodeAccess(e); // 调用节点访问后的处理方法
            return oldValue; // 返回旧值
        }
    }
    ++modCount; // 更新修改计数
    if (++size > threshold) // 更新大小并检查是否需要进行扩容
        resize();
    afterNodeInsertion(evict); // 调用节点插入后的处理方法
    return null; // 返回null,表示插入操作完成
}

 然后是对应的扩容方法resize():

当put时会判断当前元素个数是否大于阈值常量(threshold)* 负载因子常量(loadfactor),大于则将阈值 *2,也就是底层代码中的resize方法进行扩容,负载因子常量默认值为0.75F,所以一般在百分之七十五时便会触发扩容。resize方法会创建一个新的更大的数组,将原有的元素重新计算哈希位置放到新数组中。因为hashmap的大小受限于数组的最大容量,所以阈值的最大值为二的三十次方。然后数据结构,当链表长度达到一定阈值会将链表转化为红黑树

 

 

标签:分析,hash,hashMap,哈希,链表,源码,key,null,节点
From: https://www.cnblogs.com/jy6634/p/18130489

相关文章

  • Flink源码学习(4) TaskManager从节点启动分析
    taskManager是flink的worker节点,负责slot的资源管理和task执行一个taskManager就是一台服务器的抽象TaskManager基本资源单位是slot,一个作业的task会部署在一个TM的slot上运行,TM会负责维护本地的slot资源列表,并与Master和JobManager进行通信启动主类:TaskManagerRunnerTaskMan......
  • TCGA+GTEx基因表达数据合并 | 多癌种表达分析
     这个功能GEPIA2已经实现了,http://gepia2.cancer-pku.cn/#dataset但问题是它的数据不能导出,原图太丑,不能直接发表,那就没办法了,只能自己下载数据作图了。 TCGA数据可以批量下载GTEx数据也很容易下载但如何把TCGA的cancertype比对到GTEx特点组织,还是有点难度的。有些canc......
  • 读论文-基于注意力机制的浅层图像隐写分析模型
    前言今天要读的论文是一篇名为《基于注意力机制的浅层图像隐写分析模型》,文章提出了一种基于注意力机制的浅层图像隐写分析模型,通过使用一个浅层神经网络控制模型参数量和训练时间,引入注意力模块,加速模型收敛,提升模型检测的准确率。要引用本文:请使用如下格式:段明月,李爽,钟小......
  • diskperf命令是一个用于管理和配置磁盘性能计数器的实用工具,可以帮助你监视和分析磁盘
    diskperf/?DISKPERF[-Y[D|V]|-N[D|V]][\\computername] -Y 在系统重新启动时,将系统设为开启所有磁盘性能计数器。 -YD在系统重新启动时,启用物理驱动器的磁盘性能计数器。 -YV当系统重新启动时,启用逻辑驱动器的磁盘性能计数器或存储数值。 -N 当系统重新......
  • PYTHON用时变马尔可夫区制转换(MARKOV REGIME SWITCHING)自回归模型分析经济时间序列|附
    全文下载链接:http://tecdat.cn/?p=22617最近我们被客户要求撰写关于MRS的研究报告,包括一些图形和统计输出。本文提供了一个在统计模型中使用马可夫转换模型模型的例子,来复现Kim和Nelson(1999)中提出的一些结果。它应用了Hamilton(1989)的滤波器和Kim(1994)的平滑器  %matplot......
  • Hessian反序列化分析
    RPC协议RPC全称为RemoteProcedureCallProtocol(远程调用协议),RPC和之前学的RMI十分类似,都是远程调用服务,它们不同之处就是RPC是通过标准的二进制格式来定义请求的信息,这样跨平台和系统就更加方便RPC协议的一次远程通信过程如下:客户端发起请求,并按照RPC协议格式填充信息填充......
  • 基于dremio 安装包进行源码依赖包maven 私服重建的一个思路
    dremio25.0版本已经发布了,但是如果希望自己源码构建,但是缺少一些依赖造成编译会有问题,但是我们可以直接基于官方提供的下载包的文件进行maven私服的重建,以下说明下简单流程参考流程下载软件包这个可以从dremio官网下载到最好选择一个可以构建的分支本地构建下此步......
  • 20212217刘恒谦-Exp4-恶意代码分析
    一、实践过程记录1、系统运行监控(1)使用如计划任务,每隔一分钟记录自己的电脑有哪些程序在联网,连接的外部IP是哪里。运行一段时间并分析该文件,综述一下分析结果。目标就是找出所有连网的程序,连了哪里,大约干了什么(不抓包的情况下只能猜),你觉得它这么干合适不。如果想进一步分析的,......
  • 中电金信:行业智观|2023银行年报分析——金融科技发展新格局(上篇)
    ​​编辑​编辑​编辑​编辑​编辑​编辑​编辑​编辑​编辑​编辑​编辑​编辑​编辑​编辑​......
  • python计算机毕设【附源码】养老院管理系统(django+mysql+论文)
    本系统(程序+源码)带文档lw万字以上  文末可获取本课题的源码和程序系统程序文件列表系统的选题背景和意义选题背景:随着社会的快速发展,人口老龄化问题日益凸显。养老院作为为老年人提供居住、医疗、康复、娱乐等综合服务的场所,其管理水平和服务质量对老年人的生活质量有着......