Java:hashCode()和equals()的contains,Set方法的協定

本文是關於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的資料與面試題,如果你在技術上面想提升自己的話,可以關注我,私信發送領取資料或者在評論區留下自己的聯繫方式,有時間記得幫我點下轉發讓跟多的人看到哦。在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章