总结:
1.哈希又称散列,哈希算法也称散列算法
2.哈希一般指哈希算法,即将任意值(如:‘纸上得来终觉浅’)经过hash算法可得到一个固定长度的组合串(字母和数字组成),如下图:MD5与SHA-256为哈希算法中不同的输出标准。
3.哈希算法是数据查找技术中最经典的算法之一。所以有用哈希算法建立索引值,加快查询速度。
4.哈希算法具有不可逆性。
5.哈希存在"哈希碰撞"。假设f是哈希函数,y是哈希结果,x是键值,可得:y = f(x)
哈希碰撞:不同的键值(x)有可能获得相同的结果(y), 这就是hash碰撞。但是不同的y值一定对应不同的x值。
6.基于哈希的存储结构有:HashMap、HashTable等。
HashMap总结
问题1: HashMap的内部组成结构(属性)是哪些?以及作用?
问题2:HashMap的默认初始容量(桶)大小?
问题3:理解为什么HashMap底层实现是数组+链表的形式?
问题4:rehash是什么?如果禁用resize()会发生什么?
问题5:hashCode()在java中默认使用的哈希函数是什么,或者说Objects.hashCode()用了什么类型的哈希函数?
问1答:主要属性有如图:原图出自
table:很多文章都有这样的描述:是一个Entry[]数组类型。这是正确的,但HashMap中是使用Node作为table,Node是Entry的实现类。Node熟悉包括:key,value,hash,next(Node)。
size:容量,最大存储大小,也称桶大小。
loadFactor:加载因子,默认0.75。
threshold:阈值,用于判断是否需要调整容量。threshold=“size*threshold”,当HashMap中存储数据的数量达到threshold时,就需要将HashMap的容量加倍,出现resize(),rehash。
问2答:默认初始容量=16,默认的加载因子=0.75,也就是说默认阈值=12.
问3答:参考该文
问4答:rehash会发生在当需要扩容的时候,会resize()会触发,对应的key的hashCode也会发生变化,这是扩容时必要的损耗。如果人为操作禁用了resize()那么会因为人为因素形成数组链条,这是数组+链表的体现。
问5答:整理出自
经常使用的构造散列函数的方法
5.1. 直接寻址法:取keyword或keyword的某个线性函数值为散列地址。即H(key)=key或H(key) = a•key + b,当中a和b为常数(这样的散列函数叫做自身函数)
5.2. 数字分析法:分析一组数据,比方一组员工的出生年月日,这时我们发现出生年月日的前几位数字大体同样,这种话,出现冲突的几率就会非常大,可是我们发现年月日的后几位表示月份和详细日期的数字区别非常大,假设用后面的数字来构成散列地址,则冲突的几率会明显减少。因此数字分析法就是找出数字的规律,尽可能利用这些数据来构造冲突几率较低的散列地址。
5.3. 平方取中法:取keyword平方后的中间几位作为散列地址。
5.4. 折叠法:将keyword切割成位数同样的几部分,最后一部分位数能够不同,然后取这几部分的叠加和(去除进位)作为散列地址。
5.5. 随机数法:选择一随机函数,取keyword的随机值作为散列地址,通经常使用于keyword长度不同的场合。
5.6. 除留余数法:取keyword被某个不大于散列表表长m的数p除后所得的余数为散列地址。即 H(key) = key MOD p, p<=m。不仅能够对keyword直接取模,也可在折叠、平方取中等运算之后取模。对p的选择非常重要,一般取素数或m,若p选的不好,easy产生同义词。
JAVA中的Objects.hashCode()默认是使用了5.6除留余数法。所以hashMap的会与容量有关。参考出自
–
参考:
https://www.jianshu.com/p/28cc0f676488
https://blog.csdn.net/qq_34858648/article/details/79545622
https://www.cnblogs.com/acm-bingzi/p/hash.html
https://www.cnblogs.com/skywang12345/p/3310835.html
https://www.cnblogs.com/peizhe123/p/5790252.html
http://www.cnblogs.com/mengfanrong/p/4034950.html
https://blog.csdn.net/qq876551724/article/details/78814457