public V put(K key, V value) {// 调用hash(key)计算出key的hash值return putVal(hash(key), key, value, false, true);
}static final int hash(Object key) {int h;// 如果key为null,则hash值为0,否则调用key的hashCode()方法// 并让高16位与整个hash异或,这样做是为了使计算出的hash更分散return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {Node<K, V>[] tab;Node<K, V> p;int n, i;// 如果桶的数量为0,则初始化if ((tab = table) == null || (n = tab.length) == 0)// 调用resize()初始化n = (tab = resize()).length;// (n - 1) & hash 计算元素在哪个桶中// 如果这个桶中还没有元素,则把这个元素放在桶中的第一个位置if ((p = tab[i = (n - 1) & hash]) == null)// 新建一个节点放在桶中tab[i] = newNode(hash, key, value, null);else {// 如果桶中已经有元素存在了Node<K, V> e;K k;// 如果桶中第一个元素的key与待插入元素的key相同,保存到e中用于后续修改value值if (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))e = p;else if (p instanceof TreeNode)// 如果第一个元素是树节点,则调用树节点的putTreeVal插入元素e = ((TreeNode<K, V>) p).putTreeVal(this, tab, hash, key, value);else {// 遍历这个桶对应的链表,binCount用于存储链表中元素的个数for (int binCount = 0; ; ++binCount) {// 如果链表遍历完了都没有找到相同key的元素,说明该key对应的元素不存在,则在链表最后插入一个新节点if ((e = p.next) == null) {p.next = newNode(hash, key, value, null);// 如果插入新节点后链表长度大于8,则判断是否需要树化,因为第一个元素没有加到binCount中,所以这里-1if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1sttreeifyBin(tab, hash);break;}// 如果待插入的key在链表中找到了,则退出循环if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))break;p = e;}}// 如果找到了对应key的元素if (e != null) { // existing mapping for key// 记录下旧值V oldValue = e.value;// 判断是否需要替换旧值if (!onlyIfAbsent || oldValue == null)// 替换旧值为新值e.value = value;// 在节点被访问后做点什么事,在LinkedHashMap中用到afterNodeAccess(e);// 返回旧值return oldValue;}}// 到这里了说明没有找到元素// 修改次数加1++modCount;// 元素数量加1,判断是否需要扩容if (++size > threshold)// 扩容resize();// 在节点插入后做点什么事,在LinkedHashMap中用到afterNodeInsertion(evict);// 没找到元素返回nullreturn null;
}

(1)计算key的hash值;

(2)如果桶(数组)数量为0,则初始化桶;

(3)如果key所在的桶没有元素,则直接插入;

(4)如果key所在的桶中的第一个元素的key与待插入的key相同,说明找到了元素,转后续流程(9)处理;

(5)如果第一个元素是树节点,则调用树节点的putTreeVal()寻找元素或插入树节点;

(6)如果不是以上三种情况,则遍历桶对应的链表查找key是否存在于链表中;

(7)如果找到了对应key的元素,则转后续流程(9)处理;

(8)如果没找到对应key的元素,则在链表最后插入一个新节点并判断是否需要树化;

(9)如果找到了对应key的元素,则判断是否需要替换旧值,并直接返回旧值;

(10)如果插入了元素,则数量加1并判断是否需要扩容;

HashMap的put方法讲解相关推荐

  1. RestTemplate使用实战-exchange方法讲解-HTTP请求

    RestTemplate使用实战-exchange方法讲解 2019-10-28 12:40:51  阅读:160  来源: 互联网 标签:HTTP 请求 exchange RestTemplate  ...

  2. python列表方法语句_Python中列表和元组的相关语句和方法讲解

    列表(list): 首先,列表属于序列,那么序列类型可用如下内建函数-- list(iter):把可迭代对象转换为列表. str(obj):把obj对象转换为字符串,即用字符串来表示这个对象. tup ...

  3. Nginx访问控制_IP访问控制(http_access_module)原理、局限性、解决方法讲解

    Nginx访问控制_IP访问控制(http_access_module)原理.局限性.解决方法讲解 参考文章: (1)Nginx访问控制_IP访问控制(http_access_module)原理.局限 ...

  4. HashMap的遍历方法

    使用工具 IDEA2018.2 使用说明 使用迭代器,即创建Iterator对象,Iterator是一个接口,也有泛型 hasNext方法判断是否已经遍历完, next方法取当前遍历的对象 HashM ...

  5. Py之pandas:pandas的read_excel()函数中各参数说明及函数使用方法讲解

    Py之pandas:pandas的read_excel()函数中各参数说明及函数使用方法讲解 目录 pandas的read_excel()函数中各参数说明及函数使用方法讲解 read_excel()函 ...

  6. linux的python2.7的paramiko_Python使用paramiko操作linux的方法讲解

    paramiko介绍 paramiko是一个基于python编写的.使用ssh协议的模块,跟xshell和xftp功能类似,支持加密与认证,可以上传下载和访问服务器的文件. 可以利用paramiko模 ...

  7. java 语言如何判断素数_C语言实验之判断素数(循环结构java)方法讲解

    C语言实验之判断素数(循环结构java)方法讲解 Problem Description 从键盘上输入任意一个正整数,然后判断该数是否为素数. 如果是素数则输出"This is a prim ...

  8. 小米手机系统服务组件是干什么的_怎么查看小米手机MIUI系统的基本功能-小米手机MIUI系统基础功能查询方法讲解...

    小米手机是国产品牌手机中口碑较好的手机之一,受到大家的喜爱,配置功能丰富,价格实惠.亲们或许都不知道怎么查看小米手机MIUI系统的基本功能,小编很高兴为大家解决这个问题,接下来就为大家奉上小米手机MI ...

  9. HashMap的使用方法详解

    HashMap是一种十分常用的数据结构对象,可以保存键值对,下面将详细介绍HashMap的使用方法. 一.添加方法 put方法,可以单次向HashMap中添加一个键值对. 注意:添加到Map中的数据, ...

最新文章

  1. Microsoft patterns practices Enterprise Library released
  2. ASP.NET Core 1.0 使用 MySQL for EF Core 1.0 (.NET Core 1.0)
  3. 济南交警推出《酒驾整治日历》酒驾为每日必查项
  4. Biztalk 在流程中定义将消息保存为文件的文件名
  5. linux server添加硬盘,新增硬盘扩充linux ftp server空间
  6. SQL Server调优系列玩转篇三(利用索引提示(Hint)引导语句最大优化运行)
  7. Sharepoint学习笔记—Site Definition系列-- 3、创建ListDefinition
  8. 在主线程执行_深入理解JavaScript执行机制
  9. 怎么给iOS项目打包
  10. 秀米 html5 编辑工具,秀米编辑器
  11. CocosCreator查找图片引用
  12. UVA - 12235 Help Bubu 概率dp 状态压缩 记忆化搜索
  13. mkv转mp4,mkv转换mp4格式
  14. Mysql数据库开启远程连接
  15. 捋一捋这些我记不清的python概念
  16. html网页如何在手机上观看,电脑的html怎么在手机观看
  17. mac SCp上传文件到阿里云服务器centos
  18. STM32F030 IIC2通用读写24C02、24C16、24C32、24C64等例程
  19. Win7怎么连接手机热点
  20. 步进电机原理与驱动方式

热门文章

  1. 滴滴为啥值3600亿?看它的数据中台就知道了
  2. Java自动装箱与拆箱
  3. Google开源框架AutoFlip 实现视频智能剪裁
  4. 音视频技术开发周刊 80期
  5. 机器学习帮助WebRTC视频质量评价
  6. FFmpeg 硬件加速方案概览 (上)
  7. 一个运维老将的自我修养
  8. 我不是码神!Serverless真的可以为所欲为?
  9. 免费开放阅读 | 数据库管理系统的事务原理(上)
  10. EasyRTMP实现的rtmp推流的基本协议流程