23.HashMap的put方法流程

news2024/9/21 14:52:25

一、put方法的流程图


二、put方法的执行步骤

  1. 首先,根据key值计算哈希值。
  2. 然后判断table数组是否为空或者数组长度是否为0,是的话则要扩容,resize()。
  3. 接着,根据哈希值计算数组下标。
  4. 如果这个下标位置为空,添加元素即可。
  5. 如果这个下标位置不为空,则判断此下标位置的首元素的key值与要添加元素的key值是否相同,相同的话,就直接覆盖元素。
  6. 不相同的话,则判断首元素是否为树节点,是的话,则向这个红黑树中插入元素(在红黑树中插入一个新节点时,首先会遍历树以找到这个新节点应该插入的位置。在这个遍历过程中,也会检查是否已经存在相同key值的节点。如果存在,也会覆盖元素;不存在,则新节点会被插入到正确的位置)。
  7. 如果是链表的话,那就需要遍历链表,看key是否已经存在,存在则覆盖元素,不存在则在链表尾部插入元素。插入之后,如果链表长度大于等于8,则需要把链表转换为红黑树。
  8. 最后,待所有元素处理完之后,还要判断容量是否超过阈值,超过了则需要扩容。

三、对应源码:

       /**
     * Computes key.hashCode() and spreads (XORs) higher bits of hash
     * to lower.  Because the table uses power-of-two masking, sets of
     * hashes that vary only in bits above the current mask will
     * always collide. (Among known examples are sets of Float keys
     * holding consecutive whole numbers in small tables.)  So we
     * apply a transform that spreads the impact of higher bits
     * downward. There is a tradeoff between speed, utility, and
     * quality of bit-spreading. Because many common sets of hashes
     * are already reasonably distributed (so don't benefit from
     * spreading), and because we use trees to handle large sets of
     * collisions in bins, we just XOR some shifted bits in the
     * cheapest possible way to reduce systematic lossage, as well as
     * to incorporate impact of the highest bits that would otherwise
     * never be used in index calculations because of table bounds.
     */
    static final int hash(Object key) {//1.首先,根据key值计算哈希值。
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }


 /**
     * Associates the specified value with the specified key in this map.
     * If the map previously contained a mapping for the key, the old
     * value is replaced.
     *
     * @param key key with which the specified value is to be associated
     * @param value value to be associated with the specified key
     * @return the previous value associated with <tt>key</tt>, or
     *         <tt>null</tt> if there was no mapping for <tt>key</tt>.
     *         (A <tt>null</tt> return can also indicate that the map
     *         previously associated <tt>null</tt> with <tt>key</tt>.)
     */
    public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
                         //hash值
    }

    /**
     * Implements Map.put and related methods.
     *
     * @param hash hash for key
     * @param key the key
     * @param value the value to put
     * @param onlyIfAbsent if true, don't change existing value
     * @param evict if false, the table is in creation mode.
     * @return previous value, or null if none
     */
    final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;

//2.然后判断table数组是否为空或者数组长度是否为0,是的话则要扩容,resize()。
        if ((tab = table) == null || (n = tab.length) == 0)
            n = (tab = resize()).length;

//3.接着,根据哈希值计算数组下标。
//4.如果这个下标位置为空,添加元素即可。
        if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] = newNode(hash, key, value, null);
        else {

//5.如果这个下标位置不为空,则判断此下标位置的首元素的key值与要添加元素的key值是否相同,相同的话,就直接覆盖元素。
            Node<K,V> e; K k;
            if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k))))
                e = p;

//6.不相同的话,则判断首元素是否为树节点,是的话,则向这个红黑树中插入元素
            else if (p instanceof TreeNode)
                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);

//7.如果是链表的话,那就需要遍历链表,看key是否已经存在,存在则覆盖元素,不存在则在链表尾部插入元素。不存在则在链表尾部插入元素。插入之后,如果链表长度大于等于8,则需要把链表转换为红黑树。
            else {
                for (int binCount = 0; ; ++binCount) {
                    if ((e = p.next) == null) {
                        p.next = newNode(hash, key, value, null);
                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                            treeifyBin(tab, hash);//转为红黑树
                        break;
                    }
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        break;
                    p = e;
                }
            }
            if (e != null) { // existing mapping for key
                V oldValue = e.value;
                if (!onlyIfAbsent || oldValue == null)
                    e.value = value;
                afterNodeAccess(e);
                return oldValue;
            }
        }
        ++modCount;

//8.最后,待所有元素处理完之后,还要判断容量是否超过阈值,超过了则需要扩容。
        if (++size > threshold)
            resize();
        afterNodeInsertion(evict);
        return null;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1680186.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

fastadmin对登录token的处理

fastadmin对token的操作 最近开发遇到一个场景&#xff0c;需要绕过验证获取登录&#xff0c;所以恶补了一下这个知识点&#xff0c;这个主要就是控制fastadmin的token的问题 代码分步实现 class Xcxuser extends Api {//关于鉴权protected $noNeedLogin [login,getopenid,…

踩坑小结:Linux安装python环境 、安装OpenSSL

一、查看python版本 查看发现&#xff0c;linux上自带了python&#xff0c;不过是2.x版本的。 二、下载python3 2.1 下载 www.python.org/downloads/s… 可在当前目录下找到相对应的版本或者最新版本下载 也可以直接下载 Python 3.10.4 下载完在服务器上选择一个目录存放…

ffmpeg使用xfade的转场特效

ffmpeg使用xfade的转场特效 1. 介绍2. ffmpeg里面的xfade3. 使用 1. 介绍 参考文档 ffmpeg是一个音视频编辑工具&#xff0c;具体的。。。。我才搞接触&#xff0c;所以不懂。 xfade是一种视频转场滤镜&#xff0c;用于在两个视频片段之间创建平滑的过渡效果。xfade的转场效果…

扭亏为盈的赛力斯,真正进入稳态了吗?

“72小时内大定破1万台”。5月15日&#xff0c;问界新M5开启全国大规模交付&#xff0c;从当前取得的成绩来看&#xff0c;赛力斯的“富贵”似乎还将延续。 其实&#xff0c;此前基于问界新M7等车型的爆火&#xff0c;赛力斯已经找到了创收轨道。财报显示&#xff0c;2024年一…

戒烟网站|基于SSM+vue的戒烟网站系统的设计与实现(源码+数据库+文档)

戒烟网站 目录 基于SSM&#xff0b;vue的戒烟网站系统的设计与实现 一、前言 二、系统设计 三、系统功能设计 1网站功能模块 2管理员功能模块 3用户功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主…

每日5题Day3 - LeetCode 11 - 15

每一步向前都是向自己的梦想更近一步&#xff0c;坚持不懈&#xff0c;勇往直前&#xff01; 第一题&#xff1a;11. 盛最多水的容器 - 力扣&#xff08;LeetCode&#xff09; class Solution {public int maxArea(int[] height) {//这道题比较特殊&#xff0c;因为两边是任意…

OPC-UA open62541 C++测试代码

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 这是之前写的open62541测试代码…

电脑版的学浪课程下载方法

想在你的电脑上无限制地访问你最爱的学浪课程吗&#xff1f;现在&#xff0c;让我揭秘如何用几个简单步骤&#xff0c;轻松下载任何学浪课程到你的电脑&#xff0c;让学习不再受时间和地点的限制&#xff0c;随时随地都是你的课堂。 下载学浪视频的工具&#xff0c;我已经打包…

计算机网络实验3:路由器安全防控配置

实验目的和要求 理解标准IP访问控制列表的原理及功能理解CHAP、DHCP配置原理了解家用式无线路由配置方法实验项目内容 标准IP访问控制列表配置 CHAP验证路由器上配置DHCP网络地址转换NAT配置无线路由实现实验环境 1. 硬件&#xff1a;PC机&#xff1b; 2. 软件&#xff1a;W…

SQL复习

SQL基础 包括&#xff1a; 数据查询&#xff1a;SELECT数据定义语言&#xff1a;CREATE、ALTER和DROP数据操纵语言&#xff1a;INSERT、UPDATE、DELETE数据控制语言&#xff1a;GRANT、REVOKE 特点&#xff1a; 综合统一高度非过程化面向集合既是独立的也是嵌入式语言 三…

垃圾分类管理系统java项目

文章目录 垃圾分类管理系统一、项目演示二、项目介绍三、系统部分功能截图四、部分代码展示五、底部获取项目&#xff08;9.9&#xffe5;带走&#xff09; 垃圾分类管理系统 一、项目演示 垃圾分类管理系统 二、项目介绍 系统角色&#xff1a;管理员、用户 1、登录、注册功能…

【Arduino】Free RTOS系统

目录 1、任务创建 2、任务删除 3、延迟函数 4、示例&#xff1a; ESP32的SDK包中内置了FreeRTOS&#xff0c;在FreeRTOS中&#xff0c;线程&#xff08;Thread&#xff09;和任务&#xff08;Task&#xff09;的概念是相同的。每个任务就是一个线程&#xff0c;有着自己的一…

Go框架三件套:Gorm的基本操作

1.概述 这里的Go框架三件套是指 Web、RPC、ORM框架&#xff0c;具体如下: Gorm框架 gorm框架是一个已经迭代了10年的功能强大的ORM框架&#xff0c;在字节内部被广泛使用并且拥有非常丰富的开源扩展。 Kitex框架 Kitex是字节内部的Golang微服务RPC框架&#xff0c;具有高性能…

IDEA不能创建新项目和新模块

问题&#xff1a; IDEA不管是创建新项目还是新模块都创建不成功&#xff0c;会报如下图错误 解决方案&#xff1a; 在电脑设置里搜索 “防火墙和网络保护” &#xff0c;打开如下图所示 找到你所安装的IDEA&#xff0c;更改设置&#xff0c;选中IDEA 最后&#xff0c;确定&am…

行为驱动开源免费接口测试框架:karate

什么是行为驱动测试&#xff1a; 行为驱动测试&#xff08;Behavior-Driven Testing&#xff0c;简称 BDT&#xff09;是一种测试方法&#xff0c;旨在通过描述系统行为和功能来编写测试用例。BDT的重点是从用户的角度出发&#xff0c;描述系统应该如何行为&#xff0c;而不是专…

机器学习笔记 KAN网络架构简述(Kolmogorov-Arnold Networks)

一、简述 在最近的研究中,出现了号称传统多层感知器 (MLP) 的突破性替代方案,重塑了人工神经网络 (ANN) 的格局。这种创新架构被称为柯尔莫哥洛夫-阿诺德网络 (KAN),它提出了一种受柯尔莫哥洛夫-阿诺德表示定理启发的函数逼近的方法。 与 MLP 不同,MLP 依赖于各个节…

嗨动PDF编辑器怎么对pdf修改?分享修改步骤

嗨动PDF编辑器怎么对pdf修改&#xff1f;PDF&#xff08;Portable Document Format&#xff09;格式因其跨平台、不易修改的特性&#xff0c;在日常工作和学习中得到了广泛的应用。然而&#xff0c;当需要对PDF文件进行修改时&#xff0c;许多人可能会感到困扰。此时&#xff0…

付费解锁隐藏动力和续航,订阅制又被特斯拉玩出花了

我们知道&#xff0c;「订阅制」早已成互联网领域各路大厂玩烂的操作。 上到程序订阅付费使用&#xff08;例如 Offics、Adobe&#xff09;&#xff0c;下到各类功能服务订阅&#xff08;如影视会员、网盘会员等&#xff09;。 甚至于某东、某宝等网购平台也整出了 VIP 订阅服…

2024五月母亲节嘉年华活动方案

2024以花之名 致谢母亲簪花趣味亲子五月母亲节嘉年华活动方案-43P 活动策划信息&#xff1a; 方案页码&#xff1a;43页 文件格式&#xff1a;PPT 方案简介&#xff1a; 岁月温柔治愈 母爱闪闪发光 一年一度的PY圈孝子孝女大赛即将到来 本次母亲节&#xff0c;“以花之名…

三分钟快速上手SpringSecurity框架

导入依赖框架 web 框架(spring-boot-starter-web) <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency> springSecurity 框架(spring-boot-starter-security) <de…