HashMap如何解决哈希冲突?

简介: HashMap如何解决哈希冲突?

1. Hash算法和Hash表


了解Hash冲突首先了解Hash算法和Hash表


image.png

  1. Hash算法就是把任意长度的输入通过散列算法变成固定长度的输出,这个输出结果就是一个散列值


  1. Hash表又叫做“散列表”,它是通过key直接访问到内存存储位置的数据结构,在具体的实现上,我们通过Hash函数,把key映射到表中的某个位置,来获取这个位置的数据,从而加快数据的查找



2. Hash冲突


Hash冲突是由于哈希算法,被计算的数据是无限的,而计算后的结果的范围是有限的,总会存在不同的数据,经过计算之后得到值是一样,那么这个情况下就会出现所谓的哈希冲突



3. 解决Hash冲突的方法有四种


  1. 开放定址法也称线性探测法,就是从发生冲突的那个位置开始,按照一定次序从Hash表找到一个空闲位置然后把发生冲突的元素存入到这个位置,而在java中,ThreadLocal就用到了线性探测法来解决Hash冲突


image.png

如图,在Hash表索引1的位置存了key=name,再向它添加key=hobby的时候,假设计算得到的索引也是1,那么这个时候发生哈希冲突,而开放开放定址法就是按照顺序向前找到一个空闲的位置,来存储这个冲突的key


2.链式寻址法,这是一种常见的方法,简单理解就是把存在Hash冲突的key,以单向链表来进行存储,比如HashMap

image.png
如图存在冲突的key直接以单向链表的方式去进行存储


  1. 再Hash法,就是通过某个Hash函数计算的key,存在冲突的时候,再用另外一个Hash函数对这个可以进行Hash,一直运算,直到不再产生冲突为止,这种方式会增加计算的一个时间,性能上呢会有一些影响


  1. 建立公共移除区,就是把Hash表分为基本表和益处表两个部分,凡是存在冲突的元素,一律放到益处表中



4.HashMap在JDK1.8版本的优化


HashMap在JDK1.8版本中是通过链式寻址法以及红黑树来解决Hash冲突的问题,其中红黑树是为了优化Hash表的链表过长导致时间复杂度增加的问题,当链表长度大于等于8并且Hash表的容量大于64的时候,再向链表添加元素,就会触发链表向红黑树的一个转化



相关文章
|
8天前
|
存储 算法 Java
面试必备!一文搞懂HashMap如何优雅处理哈希冲突
大家好,我是小米,一个积极的程序员。今天聊聊Java面试中的常见问题——“HashMap是怎么解决哈希冲突的?”。通过一个小故事,我们了解到HashMap使用链地址法(JDK 1.8前)和红黑树(JDK 1.8后)来处理哈希冲突。链地址法用链表存储冲突的元素,而红黑树在链表长度超过8时启用,提升查找效率。希望这个讲解能帮助你更好地理解HashMap的工作原理。欢迎留言讨论,关注我的公众号“软件求生”,获取更多技术干货!
24 3
|
7月前
|
存储 算法 安全
深入了解哈希映射(HashMap)
哈希映射是现代软件开发中不可或缺的一种数据结构,它通过独特的存储和检索机制,提供了高效的数据处理能力。正确理解和使用哈希映射,能够显著提高软件性能和开发效率。不论是在日常的软件开发还是在处理大规模数据集时,哈希映射都是一个极佳的选择。
139 1
|
5月前
|
Java
【Java集合类面试十四】、HashMap是如何解决哈希冲突的?
HashMap解决哈希冲突的方法是通过链表和红黑树:当链表长度超过一定阈值时,转换为红黑树以提高性能;当链表长度缩小到另一个阈值时,再转换回链表。
|
7月前
|
存储 算法 Java
Java查找算法概览:二分查找适用于有序数组,通过比较中间元素缩小搜索范围;哈希查找利用哈希函数快速定位,示例中使用HashMap存储键值对,支持多值关联。
【6月更文挑战第21天】Java查找算法概览:二分查找适用于有序数组,通过比较中间元素缩小搜索范围;哈希查找利用哈希函数快速定位,示例中使用HashMap存储键值对,支持多值关联。简单哈希表实现未涵盖冲突解决和删除操作。
73 1
|
8月前
|
存储 缓存 Rust
Rust 笔记:Rust 语言中哈希结构(哈希映射,HashMap)、集合(哈希集,HashSet)及其使用
Rust 笔记:Rust 语言中哈希结构(哈希映射,HashMap)、集合(哈希集,HashSet)及其使用
1069 0
|
算法 Java
Java HashMap 的中 key 的哈希值是如何计算的,为何这么计算?
Java HashMap 的中 key 的哈希值是如何计算的,为何这么计算?
Java HashMap 的中 key 的哈希值是如何计算的,为何这么计算?
|
存储 Python Java
LeetCode 706:设计哈希映射 Design HashMap
题目: 不使用任何内建的哈希表库设计一个哈希映射 具体地说,你的设计应该包含以下的功能 put(key, value):向哈希映射中插入(键,值)的数值对。如果键对应的值已经存在,更新这个值。 get(key):返回给定的键所对应的值,如果映射中不包含这个键,返回-1。
1073 0
|
算法
由HashMap哈希算法引出的求余%和与运算&转换问题
1、引出问题   在前面讲解 HashMap  的源码实现时,有如下几点:   ①、初始容量为 1>16   第三步:取模运算:(n-1) & hash 1 static final int hash(Object key) { 2 int h; 3 return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); 4 } 5 6 tab[i = (n - 1) & hash];   ps:第 6 行代码是我自己加的。
1408 0
|
3月前
|
Java
让星星⭐月亮告诉你,HashMap中保证红黑树根节点一定是对应链表头节点moveRootToFront()方法源码解读
当红黑树的根节点不是其对应链表的头节点时,通过调整指针的方式将其移动至链表头部。具体步骤包括:从链表中移除根节点,更新根节点及其前后节点的指针,确保根节点成为新的头节点,并保持链表结构的完整性。此过程在Java的`HashMap$TreeNode.moveRootToFront()`方法中实现,确保了高效的数据访问与管理。
33 2
|
3月前
|
Java 索引
让星星⭐月亮告诉你,HashMap之往红黑树添加元素-putTreeVal方法源码解读
本文详细解析了Java `HashMap` 中 `putTreeVal` 方法的源码,该方法用于在红黑树中添加元素。当数组索引位置已存在红黑树类型的元素时,会调用此方法。具体步骤包括:从根节点开始遍历红黑树,找到合适位置插入新元素,调整节点指针,保持红黑树平衡,并确保根节点是链表头节点。通过源码解析,帮助读者深入理解 `HashMap` 的内部实现机制。
48 2

热门文章

最新文章