Hashcode的特性
Hashcode主要用于查询的快捷性,如Hashtable,HashMap等,Hashcode用于确定对象的存储地址
俩个对象相同,equals返回true,Hashcode一定相同
俩个对象Hashcode相同,equals不一定返回true,只能说明俩个对象存储在同一个散列结构中
重写equals,尽量重现Hashcode;equals要和Hashcode保持一致性,白话解释就是生成hashcode的属性和equals中比较使用的属性要相同
Hashcode的作用
java集合中的俩个类,List有序集合,Set无序集合,而且不能包含相同的元素;如果不用Hashcode,Set每次添加新元素的时候,需要遍历集合或者二分查找,调用equals判断是否已经相同元素存在,当元素有10000过时候,效率低下;于是Java就采用了哈希原理;
哈希算法也叫散列算法,是依照特定算法将数据直接指定到特定位置上。当添加新元素时直接调用Hashcode计算应该存储的特定物理位置
1)如果当前位置没有元素,就直接将它存储在特定位置;
2)如果当前位置有元素,就调用equals判断是否相同,相同就不存储;
3)如果当前位置有元素,而且不相同,也就时发生了Hash key冲突,那么就在这Hash key位置建立一个单链表,在该链表中存储hashcode相同的元素,这样就会降低调用equals的次数。
Hashcode实践
Hashcode用于查找元素,equals用于用于比较俩个元素是否相等
我们这里做一个测试
下面这个类有个字段叫id,我们的预期是id的对象是同一个对象,将该类对象添加到HashSet中
import java.util.HashSet;
import java.util.Set;
public class HashTest {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public int hashCode() {
return id%10;
}
public final static void main(String[] args) {
HashTest a = new HashTest();
HashTest b = new HashTest();
a.setId(1);
b.setId(1);
Set<HashTest> set = new HashSet<HashTest>();
set.add(a);
set.add(b);
System.out.println(a.hashCode() == b.hashCode());
System.out.println(a.equals(b));
System.out.println(set);
}
}
打印结果:
true
false
[HashTest@1, HashTest@1]
测试结果不符合我们预期,Hashcode相同并是相同的对象;
下面继续重写equals:
import java.util.HashSet;
import java.util.Set;
public class HashTest {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (!(obj instanceof HashTest)) {
return false;
}
HashTest other = (HashTest) obj;
if (other.getId() == this.getId()) {
return true;
}
return false;
}
@Override
public int hashCode() {
return id%10;
}
public final static void main(String[] args) {
HashTest a = new HashTest();
HashTest b = new HashTest();
a.setId(1);
b.setId(1);
Set<HashTest> set = new HashSet<HashTest>();
set.add(a);
set.add(b);
System.out.println(a.hashCode() == b.hashCode());
System.out.println(a.equals(b));
System.out.println(set);
}
}
打印结果:
true
true
[HashTest@1]
打印结果符合预期,Set中只存入了一份对象