Java中所有的类都继承了Object超类,因此每个对象都有equals()方法。
在Java中,每个对象都可以调用自己的hashCode()方法得到自己的哈希值/散列码(hash code),相当于一个独立的指纹信息,由对象导出的一个整型值,可以是负数,具有无规律性。可以利用hashCode来做一些提前的判断,如:
- 如果两个对象的hashCode不相同,那么这两个对象肯定是不同的对象。
- 如果两个对象的hashCode相同,不代表这两个对象是同一个对象,也可能是两个对象
- 如果两个对象相等,那么他们的hashCode就一定相同
在Java中比较两个对象是否相等时,会根据上述原则,先调用对象的hashCode进行比较,再进一步调用equals()方法进行比较。由于Object类中equals()方法用于检测两个对象是否相等如果两个对象引用相等,则两个对象肯定相等,通常其实现逻辑较复杂,而hashCode主要是得到一个哈希值,实际上只有数字,相对而言简单,所有通常会先比较hashCode。
这也就产生了一个问题:
如果我们重写了equals()方法,那么就要注意hashCode()方法。保证能遵守上述原则。通常有必要也重写hashCode()方法。
1.创建一个User类。(当没有重写hashCode()方法时)
public class User {
private String name;
public User(String name){
this.name = name;
}
public String getName(){
return name;
}
@Override
public boolean equals(Object obj){
User user = (User) obj;
return user.getName().equals(this.name);
}
// @Override
// public int hashCode() {
// return name.hashCode();
// }
}
2.创建Main类
import java.util.HashMap;
public class Main {
public static void main(String[] args){
HashMap<User, String> hashMap = new HashMap<>();
hashMap.put(new User("qiubai"), "123");
System.out.println(hashMap.get(new User("qiubai")));
}
}
生成的结果:
NULL
1.当在User类中重写了*hashCode()*方法后
@Override
public boolean equals(Object obj){
User user = (User) obj;
return user.getName().equals(this.name);
}
@Override
public int hashCode() {
return name.hashCode();
}
因为所引用的参数只有name,所有只需要按照equals()方法中的重写规则去修改即可。
生成的结果:
123
PS:在进行 a.equals(b) 时,如果这时a为 NULL 程序会报空指针异常,而当b为 NULL 时,执行结果只为false但不会报空指针异常,所有通常把明确的常量值放在前面。