HashMap解决hash冲突的方法

在Java中,HashMap中是用哪些方法来解决哈希冲突的? 来看一道题,问HashMap是用下列哪种方法来解决哈希冲突的? A 开放地址法 B 二次哈希法 C 链地址法 D 建立一个公共溢出区 答案是:C 解决哈希冲突的方法有三种,分别是: 开放地址法:寻找下一个为空的数组下标,而后将冲突元素存储 再散列法(二次哈希法):再次使用一个不同的哈希算法再计算一次 (第一次%16换另一个数进行%运算) 链地址法(拉链法):将所有冲突元素按照链表存储... 阅读详情

       在Java编程语言中,最基本的结构就是两种,一种是数组,一种是模拟指针(引用),所有的数据结构都可以用这两个基本结构构造,HashMap也一样。当程序试图将多个 key-value 放入 HashMap 中时,以如下代码片段为例:

HashMap<String,Object> m=new HashMap<String,Object>(); 
m.put("a", "rrr1"); 
m.put("b", "tt9"); 
m.put("c", "tt8"); 
m.put("d", "g7"); 
m.put("e", "d6"); 
m.put("f", "d4"); 
m.put("g", "d4"); 
m.put("h", "d3"); 
m.put("i", "d2"); 
m.put("j", "d1"); 
m.put("k", "1"); 
m.put("o", "2"); 
m.put("p", "3"); 
m.put("q", "4"); 
m.put("r", "5"); 
m.put("s", "6"); 
m.put("t", "7"); 
m.put("u", "8"); 
m.put("v", "9");

        HashMap 采用一种所谓的“Hash 算法”来决定每个元素的存储位置。当程序执行 map.put(String,Obect)方法 时,系统将调用String的 hashCode() 方法得到其 hashCode 值——每个 Java 对象都有 hashCode() 方法,都可通过该方法获得它的 hashCode 值。得到这个对象的 hashCode 值之后,系统会根据该 hashCode 值来决定该元素的存储位置。源码如下:

Java代码   收藏代码
  1.    public V put(K key, V value) {  
  2.         if (key == null)  
  3.             return putForNullKey(value);  
  4.         int hash = hash(key.hashCode());  
  5.         int i = indexFor(hash, table.length);  
  6.         for (Entry<K,V> e = table[i]; e != null; e = e.next) {  
  7.             Object k;  
  8.             //判断当前确定的索引位置是否存在相同hashcode和相同key的元素,如果存在相同的hashcode和相同的key的元素,那么新值覆盖原来的旧值,并返回旧值。  
  9.             //如果存在相同的hashcode,那么他们确定的索引位置就相同,这时判断他们的key是否相同,如果不相同,这时就是产生了hash冲突。  
  10.             //Hash冲突后,那么HashMap的单个bucket里存储的不是一个 Entry,而是一个 Entry 链。  
  11.             //系统只能必须按顺序遍历每个 Entry,直到找到想搜索的 Entry 为止——如果恰好要搜索的 Entry 位于该 Entry 链的最末端(该 Entry 是最早放入该 bucket 中),  
  12.             //那系统必须循环到最后才能找到该元素。  
  13.             if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {  
  14.                 V oldValue = e.value;  
  15.                 e.value = value;  
  16.                 return oldValue;  
  17.             }  
  18.         }  
  19.         modCount++;  
  20.         addEntry(hash, key, value, i);  
  21.         return null;  
  22.     }  
  23.    

       上面程序中用到了一个重要的内部接口:Map.Entry,每个 Map.Entry 其实就是一个 key-value 对。从上面程序中可以看出:当系统决定存储 HashMap 中的 key-value 对时,完全没有考虑 Entry 中的 value,仅仅只是根据 key 来计算并决定每个 Entry 的存储位置。这也说明了前面的结论:我们完全可以把 Map 集合中的 value 当成 key 的附属,当系统决定了 key 的存储位置之后,value 随之保存在那里即可.HashMap程序经过我改造,我故意的构造出了hash冲突现象,因为HashMap的初始大小16,但是我在hashmap里面放了超过16个元素,并且我屏蔽了它的resize()方法。不让它去扩容。这时HashMap的底层数组Entry[]   table结构如下: 

   

       Hashmap里面的bucket出现了单链表的形式,散列表要解决的一个问题就是散列值的冲突问题,通常是两种方法:链表法和开放地址法。链表法就是将相同hash值的对象组织成一个链表放在hash值对应的槽位;开放地址法是通过一个探测算法,当某个槽位已经被占据的情况下继续查找下一个可以使用的槽位。java.util.HashMap采用的链表法的方式,链表是单向链表。形成单链表的核心代码如下:

 

Java代码   收藏代码
  1. void addEntry(int hash, K key, V value, int bucketIndex) {  
  2.     Entry<K,V> e = table[bucketIndex];  
  3.     table[bucketIndex] = new Entry<K,V>(hash, key, value, e);  
  4.     if (size++ >= threshold)  
  5.         resize(2 * table.length);  
  6. bsp;  

     上面方法的代码很简单,但其中包含了一个设计:系统总是将新添加的 Entry 对象放入 table 数组的 bucketIndex 索引处——如果 bucketIndex 索引处已经有了一个 Entry 对象,那新添加的 Entry 对象指向原有的 Entry 对象(产生一个 Entry 链),如果 bucketIndex 索引处没有 Entry 对象,也就是上面程序代码的 e 变量是 null,也就是新放入的 Entry 对象指向 null,也就是没有产生 Entry 链。

       HashMap里面没有出现hash冲突时,没有形成单链表时,hashmap查找元素很快,get()方法能够直接定位到元素,但是出现单链表后,单个bucket 里存储的不是一个 Entry,而是一个 Entry 链,系统只能必须按顺序遍历每个 Entry,直到找到想搜索的 Entry 为止——如果恰好要搜索的 Entry 位于该 Entry 链的最末端(该 Entry 是最早放入该 bucket 中),那系统必须循环到最后才能找到该元素。

       当创建 HashMap 时,有一个默认的负载因子(load factor),其默认值为 0.75,这是时间和空间成本上一种折衷:增大负载因子可以减少 Hash 表(就是那个 Entry 数组)所占用的内存空间,但会增加查询数据的时间开销,而查询是最频繁的的操作(HashMap 的 get() 与 put() 方法都要用到查询);减小负载因子会提高数据查询的性能,但会增加 Hash 表所占用的内存空间。


三相电机控制入门:端电压、相电压、线电压到底怎么测?(附实测波形对比) 本文为三相电机控制初学者提供了端电压、相电压和线电压的完整测量指南。通过厘清三者的物理定义与测量方法,详细讲解了如何搭建虚拟星形点电路,并对比分析了方波、SPWM和SVPWM三种主流控制模式下关键电压波形的核心特征与差异,帮助工程师掌握正确的示波器测量与波形解读技巧。 阅读详情

相关推荐

企业IT运维实录:批量部署银河麒麟V10-SP1,Ghost镜像与UKey激活实战

本文详细介绍了企业级银河麒麟V10-SP1操作系统的批量部署全流程,包括标准化镜像制作、自动化封装技术、网络化部署方案及UKey集群激活方案。通过实战案例和技术要点解析,帮助企业IT运维团队大幅提升部署效率,确保系统安全与稳定性。

weixin_30729609的博客 387

HashMap hash碰撞分析

HashMap 采用一种所谓的“Hash 算法”来决定每个元素的存储位置。当程序执行 map.put(String,Obect)方法 时,系统将调用String的 hashCode() 方法得到其 hashCode 值——每个 Java 对象都有 hashCode() 方法,都可通过该方法获得它的 hashCode 值。得到这个对象的 hashCode 值之后,系统会根据该 hashCode

yongfeng596的专栏 2429

pytorch图像分类篇: 花分类数据集下载和AlexNet网络搭建训练

一、花分类数据集下载 data_setdata_set该文件夹是用来存放训练数据的目录 使用步骤如下: (1)在data_set文件夹下创建新文件夹"flower_data" (2)点击链接下载花分类数据集 (3)解压数据集到flower_data文件夹下 (4)执行"flower_data.py"脚本自动将数据集划分成训练集train和验证集val ├── flower_data ├── flower_photos(解压的数据集文件夹,3670个样本) ...

橙子的博客 8217

hashmap hash冲突怎么解决_HashMap的冲突解决

HashMap的put 和get 方法实现原理: 源码来自JDK1.8.HashMap解决冲突的方法, 先用线性链表来保存冲突,如果冲突链表长度超过8,则使用红黑树结构。final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {Node[] tab; Node p; int n, i;if ((tab...

weixin_39814925的博客 226

vcs中systemverilog和c/c++联合仿真

前言 systemverilog中,可以通过DPI、PLI来与外部其它语言的程序进行交互。PLI又分为三类,TF、ACC和VPI,可以认为是PLI技术的三代演进: 其中VPI(PLI3.0)是TF/ACC的一个超集,目前使用的PLI基本上都是VPI。 与PLI技术相独立的另一个技术就是DPI,DPI技术简化了systemverilog与foreign language的交互步骤,对于开发者相对友好,所以使用相对广泛一些。 本文不对DPI中程序调用/数据交互展开讨论(这部分可以参考绿皮书..

kevindas的博客 1万+

Unity——Scroll View 滑动居中、居中的放大、其他的缩小(支持横竖Scroll View)

一、效果 二、上代码,两种方式。 (第一种是在Update中用插值完成的,如果不想再项目中看到Update,下面的另一种改了一段用DoTween实现的,需要导入一下DoTween) using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using Unit...

SiReSo 7659

HashMap如何解决hash冲突?

补充:在JDK1.8中HashMap通过链式寻址法以其红黑树来解决哈希冲突的,其中红黑树是为了优化哈希表的链表过长。导致遍历时间复杂度增加的问题。当链表长度大于8并且哈希表的容量大于64,再向链表中添加元素,会转化为红黑树。

weixin_43763697的博客 7925

Android13无重力感应系统修改触摸屏跟随屏幕显示旋转方向旋转

在实际产品中设计时会移除重力传感器。当设备缺少重力传感器时,系统无法使用该传感器提供的方向数据来确定屏幕旋转的方向。Android 系统中由于移除重力传感器导致的默认显示方向旋转引起触摸屏与屏幕显示不一致问题,主要是由于缺乏方向检测和触摸坐标的正确转换。通过使用替代传感器(如陀螺仪)、手动配置方向、调整触摸事件坐标和 UI 布局,可以解决这个问题。开发者需要确保在设备没有重力传感器的情况下,能够通过其他方法推测方向,并确保触摸事件和 UI 动作能够正确响应设备的旋转。

weixin_35723192的博客 803

HashMap解决冲突的四种方法

1. 开放地址法 线性探测再散列 图片转自:https://blog.csdn.net/yeiweilan/article/details/73412438 放入元素,如果发生冲突,就往后找没有元素的位置; 平方探测再散列 如果发生冲突,放到(冲突+1平方)的位置,如果还发生冲突,就放到(冲突-1平方)的位置;如果还有人就放到(冲突+2平方)的位置,以此类推,要是负数就倒序数。 优点 记录更...

mashaokang1314的博客 1万+

芒果YOLOv5改进55:损失函数篇之KLD:即插即用 芒果首发原创新颖|全网唯一更新KLD改进博客,通过 Kullback-Leibler 散度学习用于目标检测的高精度边界框,提升YOLOv5小目标

YOLOv5改进KLD损失函数:即插即用 原创新颖|芒果专栏独家首发

包括YOLOv5、YOLOv7、YOLOv8等模型改进 663

【NVIDIA】Jetson Orin Nano系列:编译外部驱动(交叉编译和板上编译)

Orin Nano外部驱动的开发入门,以hello world为例。使用交叉编译和板上编译两种方法

郭老二 1734

JDK1.8中HashMap如何应对hash冲突?

1 什么是hash冲突 我们知道HashMap底层是由数组+链表/红黑树构成的, 当我们通过put(key, value)向hashmap中添加元素时,需要通过散列函数确定元素究竟应该放置在数组中的哪个位置,当不同的元素被放置在了数据的同一个位置时,后放入的元素会以链表的形式,插在前一个元素的尾部,这个时候我们称发生了hash冲突。 2 如何解决hash冲突 事实上,想让hash冲突完全不发生,是...

Desperdo 1万+

Python爬取小红书种草商品评论数据:从入门到实战全攻略(附反爬+情感分析方案)

Python爬取小红书种草商品评论数据,核心是“抓包找到正确的接口+处理登录验证+合理的反爬策略”。新手不用一开始就追求多笔记批量爬取和情感分析,先把单笔记的评论抓取和存储跑通,再逐步扩展功能。我做的这个系统现在每天帮朋友爬取3-5款美妆产品的评论,自动做情感分析和关键词提取,她再也不用手动翻评论了,效率提升了80%。如果你们在开发中遇到具体问题,比如接口找不到、Cookie过期、IP被封,都可以在评论区留言,我会一一解答。后续也可以出一期小红书笔记种草数据爬取的教程,帮助大家更全面地分析竞品数据。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1349

hashmap hash冲突怎么解决_在Java中,HashMap中是用哪些方法来解决哈希冲突的?

1.基本概念哈希算法:根据设定的哈希函数H(key)和处理冲突方法将一组关键字映象到一个有限的地址区间上的算法。也称为散列算法、杂凑算法。哈希表:数据经过哈希算法之后得到的集合。这样关键字和数据在集合中的位置存在一定的关系,可以根据这种关系快速查询。非哈希表:与哈希表相对应,集合中的 数据和其存放位置没任何关联关系的集合。由此可见,哈希算法是一种特殊的算法,能将任意数据散列后映射到有限的空间上,通...

weixin_42514736的博客 2628

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

HashMap 中 hash 冲突的解决方法及原理分析

HashMap基于哈希表的Map接口的实现。此实现提供所有可选的映射操作,并允许使用null值和null键。(除了不同步和允许使用null之外,HashMap类与Hashtable大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。值得注意的是HashMap不是线程安全的,如果想要线程安全的HashMap,可以通过Collections类的静态方法synchronizedMap获得线程安全的HashMap。...

weixin_72753070的博客 3580

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

hashmap hash冲突怎么解决_Java经典面试题:HashMap解决hash冲突的方法

HashMap冲突解决方法比较考验一个开发者解决问题的能力。下文给出HashMap冲突的解决方法以及原理分析,无论是在面试问答或者实际使用中,应该都会有所帮助在Java编程语言中,最基本的结构就是两种,一种是数组,一种是模拟指针(引用),所有的数据结构都可以用这两个基本结构构造,HashMap也一样。当程序试图将多个 key-value 放入 HashMap 中时,以如下代码片段为例:H...

weixin_35801916的博客 395

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

HashMap和HashTable区别及Hash冲突解决方法

一、HashMap和HashTable主要有以下5个方面的区别: 1.继承的父类不同   Hashtable继承自Dictionary类,而HashMap继承自AbstractMap类。但二者都实现了Map接口。 2.对null对象的支持不同   HashMap是支持null键和null值的,而HashTable在遇到null时,会抛出NullPointerException异常。这并不是...

Alexlee1986的专栏 3359

java基础--HashMap解决hash冲突的方法

写的不错,记录下转载了,面试必问的。原文地址: http://xiaolu123456.iteye.com/blog/1485349在Java编程语言中,最基本的结构就是两种,一种是数组,一种是模拟指针(引用),所有的数据结构都可以用这两个基本结构构造,HashMap也一样。当程序试图将多个 key-value 放入 HashMap 中时,以如下代码片段为例:HashMap&lt;String,O...

千年似流水的博客 1万+

【Java集合】 HashMap底层原理 和 Hash冲突的解决方法

HashMap底层原理 、HashMap的扩容操作是怎么实现的、JDK1.8对红黑树进行的改动和 Hash冲突的解决方法

阿羊ing努力提供更好的Java日记〜 1204

hashmap hash冲突怎么解决_hashmap冲突的解决方法以及原理分析:

在Java编程语言中,最基本的结构就是两种,一种是数组,一种是模拟指针(引用),所有的数据结构都可以用这两个基本结构构造,HashMap也一样。当程序试图将多个 key-value 放入 HashMap 中时,以如下代码片段为例:HashMap m=new HashMap();m.put("a", "rrr1");m.put("b", "tt9");m.put("c", "tt8");m.put(...

weixin_39559559的博客 1112

HashMap中的hash()方法是如何解决哈希冲突的

通过源码深度解析HashMap中hash()方法是如何解决哈希冲突的

理想万岁万万岁的博客 265

hashmap hash冲突怎么解决_HashMap解决hash冲突的方法

在Java编程语言中,最基本的结构就是两种,一种是数组,一种是模拟指针(引用),所有的数据结构都可以用这两个基本结构构造,HashMap也一样。当程序试图将多个 key-value 放入 HashMap 中时,以如下代码片段为例:HashMap m=new HashMap();m.put("a", "rrr1");m.put("b", "tt9");m.put("c", "tt8");m.put(...

weixin_36414025的博客 1011
上一篇: 腾讯-拥抱变化
下一篇: c++ class 与 struct 的区别!
cmdssd1
博客等级 码龄17年 24粉丝 46原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值