軟件構造——equals()和hashcode()你真的會了嗎?

看到這兩個詞,我以爲我掌握了,直到複習時看到ppt中的:
在這裏插入圖片描述
好像哪裏有些不對勁!
設想下面的情景:

Person.java
public class Person{
	private final String name;
	public Person(String name){
		this.name = name;
	}
	public String getName(){
		return name;
	}
	//如果根據名字來判斷
	//這裏的equals()和hashcode()應該怎麼寫
}
Teacher.java
public class Teacher extends Person{
	private final String title;
	public Teacher(String name, String title){
		super(name)
		this.title = title;
	}
	public String getTitle(){
		return title;
	}
	//如果將name和title作爲判斷兩個對象是否相等的依據
	//這裏的equals()和hashcode()應該怎麼寫
}

如果按照ppt中的equals()函數來完成Person類中equals()函數的編寫。即:

@Override
public boolean equals(Object that){
	if (!(that instanof Person))
		return false;
	Person t = (Person)that;
	return this.name.equals(t.name);
		
}

如果客戶端這樣使用:

Person person = new Person("Li");
Teacher teacher = new Teacher("Li","assistant");
boolean ans1 = person.equals(teacher);
//假設已經完成了Teacher.java中的equals()函數
boolean ans2 = teacher.equals(person);

自己按照equals()函數"運行"一遍,將會發現ans1是true,但是ans2是false;這顯然是有問題的。
因爲equals()決定的應該是一個等價關係,即:滿足自反,對稱,傳遞。
那問題出在哪裏呢?
我們知道,a instanceof B 是判斷a是不是B類或者B類子類的一個實例。則 父類 instanceof 子類 得到true; 子類 instanceof 父類 得到false。
ppt中出現的問題,自己還真的沒有注意過。每次寫到這裏都是靠強大的ide自動生成,但是沒有仔細看過到底是什麼樣的。
在這裏插入圖片描述
看了之後,才發現eclipse自動生成用的是getClass()。

用法 功能
a instanceof B 如果a是B類的實例,或者a是B的子類的實例,則返回true
a.getClass()==b.getClass() 只有當a和b確實是同一個類的實例時,結果才爲true

結合這個表格,好像使用getClass()更合適一些。stanceof的第一個問題。

第二個問題是類似equals()函數中,參數的引用類型和引用指向的對象類型不同時,instanceof判斷使用的是哪個?
結合equals()函數可以很簡單的知道,其使用的是引用指向的對象類型。

第二個問題,引出第三個問題:當函數參數的形式類型(即參數聲明的類型)和參數對象的實際類型不同時,函數內部什麼時候使用對象實際類型?什麼時候使用參數聲明類型呢?
這個問題,類似重寫和重載時究竟調用哪個函數的問題。
編譯時便可以確定的,使用聲明的引用類型;運行時確定的使用對象實際類型。
最後一個困擾多時的問題,爲什麼重寫equls()函數還要重寫hashcode()函數?

1.使用hashcode方法提前校驗,可以避免每一次比對都調用equals方法,提高效率。
2.保證是同一個對象,如果重寫了equals方法,而沒有重寫hashcode方法,會出現equals相等的對象,hashcode不相等的情況,重寫hashcode方法就是爲了避免這種情況的出現。

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