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. 保研夏令营的个人陈述怎么写?
  2. 使用结构体输出员工工资表
  3. python多线程同步与互斥_Python之多线程:线程互斥与线程同步
  4. python 数值运算 m op n_python数值运算 四则运算
  5. python 监视图_python获取zabbix监控图
  6. hexo的landfarz主题侧栏靠左
  7. TEN网格数据导入oracle,开源-Solidity 分散的oracle网络的示例链链接。-糯米PHP
  8. office2010过期解决办法
  9. 基于低代码平台实现物流行业的知识文档管理系统
  10. 天猫官方出品运营宝典-小二带你解读行业趋势
  11. 19c(19.3) 单机数据库安装
  12. VMware虚拟机鼠标失灵怎么办
  13. 关于t00ls的挂机脚本
  14. 如何用Go语言创建WebSocket服务
  15. 第39天:WEB攻防-通用漏洞CSRFSSRF协议玩法内网探针漏洞利用
  16. acer 4750 Fn+亮度键(左右方向键亮度调节)无效问题的解决办法
  17. AutoJs学习-实现成语查询
  18. 火山视窗CEF浏览器用网页框架操作实现取本机IP、地址
  19. python中true是什么意思_Python解惑之True和False详解
  20. 蚂蚁金服崔恒斌:金融智能——对话机器人新形态

热门文章

  1. 能不能用一句话总结 HTTPS?
  2. N个Java开发常用规范技巧总结
  3. Sping+ActiveMQ整合
  4. 火山引擎视频云:坚持基础技术创新,打造极致用户体验
  5. B端运营级视频服务技术平台搭建
  6. LiveVideoStack线上交流分享 (九) —— B站的QUIC实践简介
  7. SRS流媒体服务器——单机环境搭建和源码目录介绍
  8. solr中文搜索倒排索引和数据存储结构
  9. Golang 简洁架构实战
  10. 腾讯开源 TurboTransformers:自然语言处理推理加速工具