iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >怎么理解HashMap
  • 134
分享到

怎么理解HashMap

2023-06-16 11:06:28 134人浏览 薄情痞子
摘要

这篇文章主要讲解了“怎么理解HashMap”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么理解HashMap”吧!1、HashMap添加一个键值对的过程是怎么样的?这是网上找的一张流程图,

这篇文章主要讲解了“怎么理解HashMap”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么理解HashMap”吧!

1、HashMap添加一个键值对的过程是怎么样的?

这是网上找的一张流程图,可以结合着步骤来看这个流程图,了解添加键值对的过程。

怎么理解HashMap

1.初始化table

判断table是否为空或为null,否则执行resize()方法(resize方法一般是扩容时调用,也可以调用来初始化table)。

2.计算hash值

根据键值key计算hash值。(因为hashCode是一个int类型的变量,是4字节,32位,所以这里会将hashCode的低16位与高16位进行一个异或运算,来保留高位的特征,以便于得到的hash值更加均匀分布)

怎么理解HashMap

3.插入或更新节点

根据(n - 1) & hash计算得到插入的数组下标i,然后进行判断

table[i]==null

那么说明当前数组下标下,没有hash冲突的元素,直接新建节点添加。

table[i].hash == hash &&(table[i]== key || (key != null &&  key.equals(table[i].key)))

判断table[i]的首个元素是否和key一样,如果相同直接更新value。

table[i] instanceof Treenode

判断table[i] 是否为treeNode,即table[i] 是否是红黑树,如果是红黑树,则直接在树中插入键值对。

其他情况

上面的判断条件都不满足,说明table[i]存储的是一个链表,那么遍历链表,判断是否存在已有元素的key与插入键值对的key相等,如果是,那么更新value,如果没有,那么在链表末尾插入一个新节点。插入之后判断链表长度是否大于8,大于8的话把链表转换为红黑树。

4.扩容

插入成功后,判断实际存在的键值对数量size是否超多了最大容量threshold(一般是数组长度*负载因子0.75),如果超过,进行扩容。

源代码如下:

怎么理解HashMap

2.为什么说HashMap不是线程安全的?

其实通过学习HashMap添加键值对的方法,我们可以看到整个方法内都没有使用到,所以一旦多线并发访问,就有可能造成数据不一致的问题,

例如:

如果有两个添加键值对的线程都执行到if ((tab = table) == null || (n = tab.length) ==  0)这行语句,都对table变量进行数组初始化,就会造成已经初始化好的数组table被覆盖,然后前面初始化的线程会将键值对添加到之前初始化的数组中去,造成键值对丢失。

怎么理解HashMap

3.为什么要一起重写hashCode()和equal()方法?

当我们的对象一旦作为HashMap中的key,或者是HashSet中的元素使用时,就必须同时重写hashCode()和equal()方法

首先看看hashCode()和equal()方法的默认实现

可以看到Obejct类中的源码如下,可以看到equals()方法的默认实现是判断两个对象的内存地址是否相同来决定返回结果。

怎么理解HashMap

网上很多博客说hashCode的默认实现是返回内存地址,其实不对,以Openjdk为例,hashCode的默认计算方法有5种,有返回随机数的,有返回内存地址,具体采用哪一种计算方法取决于运行时库和JVM的具体实现。

感兴趣的朋友可以看看这篇博客 blog.csdn.net/xusiwei1236…

然后看看hashCode()方法,equal()方法在HashMap中的应用

怎么理解HashMap

为了将一组键值对均匀得存储在一个数组中,HashMap对key的hashCode进行计算得到一个hash值,用hash对数组长度取模,得到数组下标,将键值对存储在数组下标对应的链表下(假设链表长度小于8,没有达到转换为红黑树的阀值)。

下面是添加键值对的putVal()方法,当数组下标对应的是一个链表时执行的代码

怎么理解HashMap

可以清楚地看到判断添加的key与链表中已存在的key是否相等的方法主要是e.hash == hash && ((k = e.key) ==  key || (key != null && key.equals(k))), 也就是:  1.先判断hash值是否相等,不相等直接结束判断,因为hash值不相等,key肯定不相等。  2.判断两个key对象的内存地址是否相等(相等指向内存中同一个对象)。  3.key不为null,调用key的equal()方法判断是否相等,因为有可能两个key在内存中存储的地址不一样,但是是相等的。 就像是

怎么理解HashMap

背景

假设我们有一个KeyObject类,假设我们认为两个KeyObject的属性a相等,那么KeyObject就是相等的相等的,我们将KeyObject作为HashMap的key,以KeyObject是否相等作为去重标准,不能重复添加KeyObject相等,value不等的值到HashMap中去

怎么理解HashMap

假设都hashCode()方法和equals()方法都不重写(结果:HashMap无法保证去重)

执行以下代码:

怎么理解HashMap

如果KeyObject的hashCode()方法和equals()方法都不重写,那么即便KeyObject的属性a都是1,key1和key2的hashCode都是不相同的,key1和key2调用equals()方法也不相等,这样hashMap中就可以同时存在key1和key2了。

打印结果:

怎么理解HashMap

假如只重写hashCode()方法(结果:无法正确地与链表元素进行相等判断,从而无法保证去重)

执行以下代码:

怎么理解HashMap

此时equal()方法的实现是默认实现,也就是当两个对象的内存地址相等时,equal()方法才返回true,虽然key1和key2的a属性是相同的,但是他们在内存中是不同的对象,所以key1==key2结果会是false,KeyObject的equals()方法默认实现是判断两个对象的内存地址,所以  key1.equals(key2)也会是false,所以这两个键值对可以重复地添加到hashMap中去。

输出结果:

怎么理解HashMap

假如只重写equals()方法(结果:映射到HashMap中不同数组下标,无法保证去重)

怎么理解HashMap

假设只equals()方法,hashCode方法会是默认实现,具体的计算方法取决于JVM,(测试时发现是内存地址不同但是相等的对象,它们的hashCode不相同),所以计算得到的数组下标不相同,会存储到hashMap中不同数组下标下的链表中,也会导致HashMap中存在重复元素。

输出结果如下:

怎么理解HashMap

感谢各位的阅读,以上就是“怎么理解HashMap”的内容了,经过本文的学习后,相信大家对怎么理解HashMap这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

--结束END--

本文标题: 怎么理解HashMap

本文链接: https://www.lsjlt.com/news/283311.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 怎么理解HashMap
    这篇文章主要讲解了“怎么理解HashMap”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么理解HashMap”吧!1、HashMap添加一个键值对的过程是怎么样的这是网上找的一张流程图,可...
    99+
    2023-06-16
  • hashmap的扩容机制怎么理解
    今天小编给大家分享一下hashmap的扩容机制怎么理解的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。hashmap的扩容机制...
    99+
    2023-07-05
  • 怎么理解Java1.7中的HashMap源码
    本篇内容主要讲解“怎么理解Java1.7中的HashMap源码”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么理解Java1.7中的HashMap源码”吧!存储结构内部包含了一个 Entry ...
    99+
    2023-06-25
  • HashMap详解
    一、HashMap集合简介 HashMap 基于哈希表的 Map 接口实现,是以 key-value 存储形式存在,即主要用来存放键值对。HashMap 的实现不是同步的,这意味着它不是线程安全的。...
    99+
    2023-09-22
    数据结构 java 链表
  • 深入理解Java中的HashMap
    目录一、HashMap的结构图示二、HashMap的成员变量以及含义2.1、hash方法说明2.2、tableSizeFor方法说明三、HashMap的构造方法四、HashMap元素...
    99+
    2024-04-02
  • 如何理解并掌握HashMap
    这篇文章主要介绍“如何理解并掌握HashMap”,在日常操作中,相信很多人在如何理解并掌握HashMap问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何理解并掌握HashMap”的疑惑有所帮助!接下来,请跟...
    99+
    2023-06-16
  • Java中HashMap怎么解决哈希冲突
    这篇文章主要介绍“Java中HashMap怎么解决哈希冲突”,在日常操作中,相信很多人在Java中HashMap怎么解决哈希冲突问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java中HashMap怎么解决哈...
    99+
    2023-06-30
  • HashMap底层原理是什么
    本篇内容介绍了“HashMap底层原理是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!HashMap存...
    99+
    2024-04-02
  • Java 中HashMap 详解
    本篇重点: HashMap的存储结构 HashMap的put和get操作过程 HashMap的扩容 关于transient关键字 HashMap的存储结构 HashMap 总体是数组+链表的存储结构, 从JDK1.8开始,当数组的长度大...
    99+
    2023-09-03
    哈希算法 散列表 java
  • HashMap的底层原理是什么
    这篇文章将为大家详细讲解有关HashMap的底层原理是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。一:HashMap的节点:HashMap是一个集合,键值对的集合,源码中每个节点用No...
    99+
    2023-06-04
  • HashMap源码怎么分析
    这篇文章主要介绍“HashMap源码怎么分析”,在日常操作中,相信很多人在HashMap源码怎么分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”HashMap源码怎么分析”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-05
  • HashMap之keyset()方法底层原理解读
    目录HashMap之keyset() 方法底层原理HashMap (jdk1.8) keySet()方法详细注释keySet()注释KetSet内部类KeyIterator实现Ite...
    99+
    2023-03-22
    HashMap keyset()方法 keyset()方法底层原理 keyset()方法
  • 什么是HashMap
    什么是HashMap,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。HashMap是一个非常重要的集合,日常使用也非常的频繁,同...
    99+
    2024-04-02
  • 怎么比较HashMap和TreeMap
    这期内容当中小编将会给大家带来有关怎么比较HashMap和TreeMap,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1.AbstractMap抽象类和SortedMap接口AbstractMap抽象类:...
    99+
    2023-06-17
  • java中hashmap怎么使用
    HashMap是Java中常用的数据结构之一,它是一个无序的键值对集合,可以存储不同类型的键和值。以下是HashMap的基本用法:1...
    99+
    2023-09-14
    java
  • 通过HashMap原理详解entrySet中的疑问
    目录HashMap底层变量put()方法:2. get(Object key)方法:3. remove(Object key)方法:4.entrySet()方法:EntrySet类代...
    99+
    2022-11-13
    HashMap entrySet HashMap 原理
  • HashMap底层原理分析
    小编给大家分享一下HashMap底层原理分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!众所周知,HashMap是一个用于存储Key-Value键值对的集合,每一个键值对也叫做Entry。这些个键值对(Entry)分散存...
    99+
    2023-06-27
  • java中怎么使用hashmap解决哈希冲突
    哈希冲突在HashMap中是通过链表解决的,即使用链表来存储冲突的元素。以下是使用HashMap解决哈希冲突的步骤:1. 创建一个H...
    99+
    2023-09-14
    java
  • rust的vector和hashmap怎么创建
    今天小编给大家分享一下rust的vector和hashmap怎么创建的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。动态数组V...
    99+
    2023-07-05
  • HashMap方法之Map.getOrDefault()怎么使用
    本篇内容介绍了“HashMap方法之Map.getOrDefault()怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!HashMap...
    99+
    2023-07-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作