Object對象的通用方法-equals、hashCode



覆蓋equals時需要遵守的通用約定
    

在覆蓋equals方法的時候,你必須要遵守它的通用約定。下面是約定的內容,來自Object的規範[JavaSE6]

自反性對於任何非null的引用值xx.equals(x)必須返回true 對稱性對於任何非null的引用值xy,當且僅當y.equals(x)返回true時,x.equals(y)必須返回true 傳遞性。對於任何非null的引用值xyz,如果x.equals(y)返回true,並且y.equals(z)也返回true,那麼x.equals(z)也必須返回true 一致性。對於任何非null的引用值xy,只要equals的比較操作在對象中所用的信息沒有被修改,多次調用該x.equals(y)就會一直地返回true,或者一致地返回false 對於任何非null的引用值xx.equals(null)必須返回false


結合以上要求,得出了以下實現高質量equals方法的訣竅:
1.
使用==符號檢查參數是否爲這個對象的引用
2.
使用instanceof操作符檢查參數是否爲正確的類型如果不是,則返回false。一般來說,所謂正確的類型是指equals方法所在的那個類。
3.
把參數轉換成正確的類型。因爲轉換之前進行過instanceof測試,所以確保會成功。
4.
對於該類中的每個關鍵域,檢查參數中的域是否與該對象中對應的域相匹配。如果這些測試全部成功,則返回true;否則返回false
5.
當編寫完成了equals方法之後,檢查對稱性傳遞性一致性

/**
 *@Function: Effective Java 8,9 Object通用方法
 *@Date: 2014-3-18
 */
public class EqualsTest {
	public static void main(String[] args) {
		//通過覆蓋equals方法實現特有的"邏輯相等"行爲
		System.out.println(new Phone(222,333).equals(new Phone(222,333)));
		//未覆蓋hashCode導致獲取不到想要的結果
		Map map=new HashMap();
		map.put(new Phone(222, 333), "April");
		System.out.println(map.get(new Phone(222,333)));
	}
}
//Effective Java 8,9 Object通用方法
final class Phone {
	private final short num1;
	private final short num2;
	public Phone(int num1,int num2){
		this.num1=(short) num1;
		this.num2=(short) num2;
	}
	/**
	 *@Function: 重寫equals以實現特有的"邏輯相等"
	 *	 注:instanceof前的參數爲null會直接返回false,所以沒必要顯式判斷null
	 */
	@Override
	public boolean equals(Object o) {
		if(this==o){
			return true;
		}
		if(!(o instanceof Phone)){
			return false;
		}
		Phone p=(Phone)o;
		return p.num1==num1&&p.num2==num2;
	}
	/**
	 *@Function: 覆蓋equals時總要覆蓋hashCode
	 *否則無法結合所有基於散列的集合一起工作(Hashtable,HashMap,HashSet..)
	 */
	@Override
	public int hashCode() {
		int result=hashCode;
		if(result==0){
		    result=17;
			result=31*result+num1;
			result=31*result+num2;
		}
		hashCode=result;
		return result;
	}
	int hashCode=0;
}


覆蓋equals時總要覆蓋hashCode
    
一個很常見的錯誤根源在於沒有覆蓋hashCode方法。在每個覆蓋了equals方法的類中,也必須覆蓋hashCode方法。如果不這樣做的話,就會違反Object.hashCode的通用約定,從而導致該類無法結合所有基於散列的集合一起正常運作,這樣的集合包括HashMapHashSetHashtable
覆蓋hashCode約定:
在應用程序的執行期間,只要對象的equals方法的比較操作所用到的信息沒有被修改,那麼對這同一個對象調用多次,hashCode方法都必須始終如一地返回同一個整數。在同一個應用程序的多次執行過程中,每次執行所返回的整數可以不一致 如果兩個對象根據equals()方法比較是相等的,那麼調用這兩個對象中任意一個對象的hashCode方法都必須產生同樣的整數結果如果兩個對象根據equals()方法比較是不相等的,那麼調用這兩個對象中任意一個對象的hashCode方法,則不一定要產生相同的整數結果。但是程序員應該知道,給不相等的對象產生截然不同的整數結果,有可能提高散列表的性能

hashCode的性能優化


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