目录
hashCode原理
- hashCode是jdk根据对象的地址算出来的一个int数字,即对象的哈希码值,代表了该对象在内存中的存储位置。
- hashCode()方法是顶级类Object类的提供的一个方法,所有的类都可以进行对hashCode方法重写。
- 比较一个类是否相同时往往会重写equals方法,值得注意的是,重写equals方法的同时必须也要重写hashCode方法,多次调用一个对象的hashCode方法必须返回同一个数字,这也是必须遵守的规范。
hashCode冲突解决
概念
当两个对象equals相同,hashCode规定也必须相同,但反过来就不一定,两个对象对应一个hashCode,但equals却并不相等。这就是hash冲突
解决方式
- 1.开放地址方法
(1)线性探测
按顺序决定哈希值时,如果某数据的哈希值已经存在,则在原来哈希值的基础上往后加一个单位,直至不发生哈希冲突。
(2)再平方探测
按顺序决定哈希值时,如果哈希值已经存在,则在原来哈希值的基础上先加1的平方个,若仍然存在则减1的平方。随之是2的平方,3的平方等等。直至不发生哈希冲突。
(3)伪随机探测
按顺序决定哈希值时,如果某数据已经存在,通过随机函数随机生成一个数,在原来哈希值的基础上加上随机数,直至不发生哈希冲突。
- 2.链式地址法(HashMap的哈希冲突解决方法)
对于相同的哈希值,使用链表进行连接。使用数组存储每一个链表。
优点:
(1)拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短;
(2)由于拉链法中各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况;
(3)开放定址法为减少冲突,要求装填因子α较小,故当结点规模较大时会浪费很多空间。而拉链法中可取α≥1,且结点较大时,拉链法中增加的指针域可忽略不计,因此节省空间;
(4)在用拉链法构造的散列表中,删除结点的操作易于实现。只要简单地删去链表上相应的结点即可。
缺点:
指针占用较大空间时,会造成空间浪费,若空间用于增大散列表规模进而提高开放地址法的效率。
- 3.建立公共溢出区
建立公共溢出区存储所有哈希冲突的数据。
- 4.再哈希法
对于冲突的哈希值再次进行哈希处理,直至没有哈希冲突。