重寫equals和hashCode方法的示例

若是一個類有本身特有的「邏輯相等」,且須要以此進行比較時,那麼就須要重寫equals方法。java

在Object的規範中,重寫equals方法有下面幾條通用約定:緩存

  • 自反性。 x.equals(x) == trueide

  • 對稱性。if   y.equals(x) == true , then  x.equals(y) == true性能

  • 傳遞性。if   x.equals(y) == true y.equals(x) == true , then x.equals(z) == truecode

  • 一致性。若是比較的對象沒有被修改,那麼屢次調用equals方法返回的結果應該相同
    對象


有個示例對象以下:
hash

public class Book {
	private long id;
	private String name;
	private boolean isPublished;
}

那麼重寫的equals方法示例以下:
class

@Override
	public boolean equals(Object obj) {
		if( !(obj instanceof Book))
			return false;
		Book b = (Book) obj;
		return b.id == id 
				&& b.isPublished == isPublished 
				&& (b.name == name || (b != null && b.equals(b.name)) );
	}



在重寫了equals方法的類中,若是不重寫hashcode方法,則全部基於hash的集合就無法正常使用。方法

重寫hashCode方法示例以下:集合

@Override
	public int hashCode() {
		int hashCode = 3;
		hashCode = 31 * hashCode + (int)(id ^ (id>>>32));
		hashCode = 31 * hashCode + (name == null?0:name.hashCode());
		hashCode = 31 * hashCode + (isPublished?1:0);
		return hashCode;
	}



若是這個類是不可變的,而且hashCode比較耗性能,則能夠考慮緩存hashCode的值。

示例以下:

        //使用volatile保證可見性
        private volatile int hashCodeCache;
	
	@Override
	public int hashCode() {
		int hashCode = hashCodeCache;
		if(hashCode == 0){
			hashCode = 3;
			hashCode = 31 * hashCode + (int)(id ^ (id>>>32));
			hashCode = 31 * hashCode + (name == null?0:name.hashCode());
			hashCode = 31 * hashCode + (isPublished?1:0);
			hashCodeCache = hashCode;
		}
		return hashCode;
	}
相關文章
相關標籤/搜索