赞
踩
大家好,我是三叔,很高兴这期又和大家见面了,一个奋斗在互联网的打工人。
哈希表是一种常见的数据结构,也被称为散列表(Hash Table)或哈希映射(Hash Map)。它通过使用哈希函数(Hash Function)将键(Key)映射到存储桶(Bucket)中,以实现高效的数据存储和检索。
hash表常见的数据结构有:数组、Set、Map。
适用场景:当需要使用一个简单的、固定大小的数据结构来存储一组元素时,可以选择数组。例如,存储一组整数、浮点数或自定义对象等。
例如要查询一个班级学生是否在这所学校里,要枚举的话时间复杂度是O(n),但如果使用哈希表的话, 只需要O(1)就可以做到。
只需要初始化把这所学校里学生的名字都存在哈希表里,在查询的时候通过索引直接就可以知道这位同学在不在这所学校里了。将学生姓名映射到哈希表上就涉及到了hash function ,也就是哈希函数。
哈希函数如下图所示,通过hashCode把名字转化为数值,一般hashcode是通过特定编码方式,可以将其他数据格式转化为不同的数值,这样就把学生名字映射为哈希表上的索引数字了。
如果hashCode得到的数值大于 哈希表的大小了,也就是大于tableSize了,怎么办呢?
此时为了保证映射出来的索引数值都落在哈希表上,我们会在再次对数值做一个取模的操作,就要我们就保证了学生姓名一定可以映射到哈希表上了。
适用场景:当需要存储一组唯一元素,并且不关心元素的顺序时,可以选择Set。常见的应用包括去重 等。
适用场景:当需要按照键值对关系存储和检索数据时,可以选择Map。常见的应用包括缓存、索引、配置信息等。
如果数据量不大的情况下,使用数组效率更高,Set和Map进行映射需要时间;如果是数据量比较大,使用Set和Map效率更高,因为底层是树,树的查找效率更高。
既然是hash函数进行计算,数据量足够多的时候或者hash函数分布不够均匀,总是会有不同学生的hash值一样,那么就会产生hash碰撞。
如图所示,小李和小王都映射到了索引下标 1 的位置,这一现象叫做哈希碰撞。哈希碰撞指的是不同的键通过哈希函数计算后得到相同的哈希值,导致它们被映射到同一个存储桶中。哈希碰撞是不可避免的,因为哈希函数的输出范围有限,而键的数量可能是无限的。
在Java中,常见的哈希表实现(如HashMap、LinkedHashMap)已经内置了处理哈希碰撞的策略,采用了链表法和开放寻址法的组合,以及负载因子和动态调整的机制。它们通过优化的哈希函数和合理的碰撞处理策略,提供了高效的键值对存储和检索功能。
哈希表是一种重要的数据结构,通过哈希函数将键映射到存储桶中。哈希碰撞是不可避免的,但我们可以通过链表法、开放寻址法、再哈希法以及负载因子的动态调整等策略来处理碰撞,以提高哈希表的性能和效率。在实际应用中,我们需要根据具体场景和需求选择合适的哈希表实现和碰撞处理策略。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。