本文是關於hashCode的,它等於Set中用於contains(Object o)方法的協定。
關於使用Set中的contains()方法的一個難題
import java.util.HashSet;
class Dog{
String color;
public Dog(String s){
color = s;
} }
public class SetAndHashCode {
public static void main(String[] args) {
HashSet dogSet = new HashSet();
dogSet.add(new Dog(“white”));
dogSet.add(new Dog(“white”));
System.out.println("We have " + dogSet.size() + " white dogs!");
if(dogSet.contains(new Dog("white"))){
System.out.println("We have a white dog!");
}else{
System.out.println("No white dog!");
}
}}
輸出:
We have 2 white dogs!
No white dog!
我們向集合中添加了兩隻白狗-dogSet,大小顯示我們有2只白狗。但是,爲什麼在使用contains()方法時沒有白狗呢?
Set的contains(Object o)方法
從Java Doc中,當且僅當此集合包含元素e使得(o == null?e == null:o.equals(e))時,contains()方法返回true。因此,contains()方法實際上使用equals()方法檢查相等性。
注意,可以將null作爲元素添加到集合中。以下代碼實際上顯示true。
HashSet a = new HashSet();
a.add(null);if(a.contains(null)){
System.out.println(“true”);}
所述公共布爾等於(對象OBJ)方法在對象類中定義。每個類(包括您自己定義的類)都將Object作爲超類,並且它是任何類層次結構的根。所有對象(包括數組)都實現此類的方法。
在您自己定義的類中,如果不顯式重寫此方法,它將具有默認實現。當且僅當兩個對象引用同一個對象(即x == y爲true)時,它才返回true。
如果將Dog類更改爲以下類別,它將起作用嗎?
class Dog{
String color;
public Dog(String s){
color = s;
}
//overridden method, has to be exactly the same like the following
public boolean equals(Object obj) {
if (!(obj instanceof Dog))
return false;
if (obj == this)
return true;
return this.color.equals(((Dog) obj).color);
}
}
答案是不。
現在問題是由Java中的hashCode和equals contract引起的。hashCode()方法是Object類中的另一個方法。
約定是,如果兩個對象相等(通過使用equals()方法),則它們必須具有相同的hashCode()。如果兩個對象具有相同的哈希碼,則它們可能不相等。
public int hashCode()的默認實現爲不同的對象返回不同的整數。在此特定示例中,因爲我們尚未定義自己的hashCode()方法,所以默認實現將爲兩個白狗返回兩個不同的整數!這違反了合同。
Set中contains()方法的解決方案
class Dog{
String color;
public Dog(String s){
color = s;
}
//overridden method, has to be exactly the same like the following
public boolean equals(Object obj) {
if (!(obj instanceof Dog))
return false;
if (obj == this)
return true;
return this.color.equals(((Dog) obj).color);
}
public int hashCode(){
return color.length();//for simplicity reason
}}
最後,開發這麼多年我也總結了一套學習Java的資料與面試題,如果你在技術上面想提升自己的話,可以關注我,私信發送領取資料或者在評論區留下自己的聯繫方式,有時間記得幫我點下轉發讓跟多的人看到哦。