在hash表操作中,hashCode()和equals()方法用於判斷兩個對象是否相等,在HashSet的contains()方法add()方法、HashMap的contains()方法和put()方法等集合框架中廣泛使用。
hashCode()和equals()方法在Object類中被定義,java中任何類都具有這兩個方法。在新定義類時,若涉及到新定義類對象的比較,則需要重寫這兩個方法。
- 如下命題成立
- 命題1:兩個對象equals()方法返回true時,hashCode()方法返回值一定相同;
重寫equals(Object obj)方法時,有必要重寫hashcode()方法,確保通過equals(Object obj)方法判斷結果爲true的兩個對象具備相等的hashcode()返回值。
-
命題1的逆否:兩個對象的hashCode()返回值不同,則equals()方法返回值一定false;
-
命題2:兩個對象equals()返回值false時,hashCode()方法值可以相等;
- 命題3:兩個對象hashCode()相等時,equals()可能爲true或false;
所以,在判斷兩個對象是否相等時,先判斷hashCode(),hashCode()不等時直接返回false;hashCode()相等時再判斷equals()方法。
- 示例代碼
- 由於Object類的hashCode()是將對象的內部地址轉換成整數來返回,所以當某個類沒有覆蓋hashCode()方法時,equals()方法將失敗。
import java.util.*;
public class Main1 {
static class Name {
String f = null;
String l = null;
public Name(String f, String l) {
this.f = f;
this.l = l;
}
// 沒有重寫hashCode()
@Override
public boolean equals(Object obj) {
Name o = (Name)obj;
return this.f.equals(o.f) && this.l.equals(o.l);
}
}
public static void main(String[] args) {
HashSet<Name> set = new HashSet<>();
Name n1 = new Name("pan", "shan");
set.add(n1);
Name n2 = new Name("pan", "shan");
boolean res = set.contains(n2);
System.out.println(res);// false
}
}
同時覆蓋equals()和hashCode()方法
import java.util.*;
public class Main1 {
static class Name {
String f = null;
String l = null;
public Name(String f, String l) {
this.f = f;
this.l = l;
}
// 同時重寫equals()和hashCode()
@Override
public boolean equals(Object obj) {
Name o = (Name)obj;
return this.f.equals(o.f) && this.l.equals(o.l);
}
@Override
public int hashCode() {
return this.f.hashCode()*31 + this.l.hashCode();
}
}
public static void main(String[] args) {
HashSet<Name> set = new HashSet<>();
Name n1 = new Name("pan", "shan");
set.add(n1);
Name n2 = new Name("pan", "shan");
boolean res = set.contains(n2);
System.out.println(res);// true
}
}