热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JAVA-HashMap源码-put方法

HashMap(1.8)HashMap的put方法:传入参数:泛型K、V是在初始化HashMap对象时指定好的代码如下:publicVput(Kk
HashMap(1.8)

HashMap的put方法:
传入参数:泛型K、V是在初始化HashMap对象时指定好的
代码如下:
public V put(K key, V value) 
{
            return putVal(hash(key), key, value, false, true);
        }

核心方法:putVal
传入参数:1.根据key计算得到的哈希值 2.key值 3.value值 4.是否改变表中已存在的值 5.
代码如下:
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) 
{
        Node[] tab; Node p; int n, i;
        if ((tab = table) == null || (n = tab.length) == 0)
                //调用resize()方法创建表
n = (tab = resize()).length;
//判断数组中是否存在对应的节点
        if ((p = tab[i = (n - 1) & hash]) == null)
            //不存在则创建新节点
tab[i] = newNode(hash, key, value, null);
        else 
{
            Node e; 
    K k;
    //判断已存在节点的key值和新传入的key值是否相等
            if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k))))
    e = p;
     //如果不相等,则判断已存在节点是否是红黑树类型
            else if (p instanceof TreeNode)
//按照红黑树的处理方式
                e = ((TreeNode)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);
                        //判断是否达到红黑树转换的阈值(binCount=0时表示链表的第一个元素,所以需要将阈值减一再进行比较)
if (binCount >= TREEIFY_THRESHOLD - 1) 
    //转换为红黑树
                            treeifyBin(tab, hash);
                        break;
                 }
 //判断链表中下个元素的key是否和新传入的key值相等,并且哈希值也相等
                 if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k))))
                        break;
//继续遍历链表中的下一个元素
                        p = e;
                 }
            }
    //判断现在的map中是否存在新key对应的元素
            if (e != null) 
    {
                //替换新value,返回旧value
V oldValue = e.value;
                if (!onlyIfAbsent || oldValue == null)
                    e.value = value;
//LinkedHashMap继承自HashMap,实现了该方法,主要目的是将节点移到双向链表尾部
                afterNodeAccess(e);
                return oldValue;
            }
        }
//数组空槽中添加了元素
//map被修改次数加一
        ++modCount;
//判断是否需要进行扩容
        if (++size > threshold)
            resize();
//LinkedHashMap实现了该方法,主要目的是移除最老的一个节点,实现LRU机制
        afterNodeInsertion(evict);
        return null;
    }

总结:

1.只有数组空槽中添加了元素,才会真正影响到HashMap的容量值,这时判断是否需要进行扩容

2.向HashMap中添加新元素,需要将将元素的值返回,如果旧元素为null,则返回null

推荐阅读
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • HashMap的相关问题及其底层数据结构和操作流程
    本文介绍了关于HashMap的相关问题,包括其底层数据结构、JDK1.7和JDK1.8的差异、红黑树的使用、扩容和树化的条件、退化为链表的情况、索引的计算方法、hashcode和hash()方法的作用、数组容量的选择、Put方法的流程以及并发问题下的操作。文章还提到了扩容死链和数据错乱的问题,并探讨了key的设计要求。对于对Java面试中的HashMap问题感兴趣的读者,本文将为您提供一些有用的技术和经验。 ... [详细]
  • 从相邻元素对还原数组的解题思路和代码
    本文介绍了从相邻元素对还原数组的解题思路和代码。思路是使用HashMap存放邻接关系,并找出起始点,然后依次取。代码使用了HashMap来存放起始点所在的adjacentPairs中的位置,并对重复的起始点进行处理。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • Whatsthedifferencebetweento_aandto_ary?to_a和to_ary有什么区别? ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
author-avatar
化妆师苹苹
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有