原創文章,轉載請標註出處:《Java基礎系列-equals方法和hashCode方法》html
equals方法和hashCode方法都是有Object類定義的。java
public class Object { public native int hashCode(); public boolean equals(Object obj) { return (this == obj); } }
任何的類都是Object類的子類,全部它們默認都擁有這兩個方法。
equals方法用於定義兩個對象的比較方式,而hashCode方法是native方法,主要用戶計算對象的hash值。算法
equals方法主要用於定義兩個對象的比較方式,默認的比較方式是比較內存地址,相對於基本類型來講就是值,而相對於引用類型來講就是堆中具體對象的地址。那麼就只有值相同的基本類型,和同一個對象的兩個引用才能相等。可是在咱們實際業務系統中,兩個對象的相等通常指的是兩個對象的內容相同(邏輯相同),而不是說它兩個是同一個對象,這種狀況使用默認的equals就沒法實現相等(由於兩個不一樣對象地址值必定不一樣),這時候咱們就須要對equals方法進行重寫,定義新的比較方式。數據結構
非空性:對於非null的x,存在x.equals(null)返回falseide
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { public boolean equals(Object anObject) { // 首先判斷兩個對象是否是同一個,地址相同否 if (this == anObject) { return true; } // 判斷給定的對象是不是String類型,這裏instanceof關鍵字是重寫equals方法時常用的一個關鍵字 // instanseof用於判斷右邊的類型是不是當前對象的類型或者超類型,超接口類型等 if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; // 校驗兩個字符串的長度相同否 if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; // 循環校驗兩個字符串中的每一個字符是否相同 while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; } }
注意,使用instanceof在針對存在子類的狀況下,可能會出現違反對稱性和傳遞性的狀況,爲了不這種狀況,能夠通給getClass的方式比較類型。
自定義重寫:函數
public class EqualsTest { private int id; public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public boolean equals(Object obj) { // 知足非空性 if(obj == null){ return false; } // 知足自省性 if(this == obj){ return true; } // 知足對稱性、傳遞性、一致性 if(this.getClass() == obj.getClass() && this.getClass().getClassLoader() == obj.getClass().getClassLoader() && this.id == ((EqualsTest)obj).getId()){ return true; } return false; } }
注意:這裏若是是有不一樣的類加載器加載的同一類的實例也是沒法相等的。this
hashCode通常用於計算對象的hash值,它在類重寫equals的時候一塊兒重寫,重寫它的目的是爲了保證equals相同的兩個對象的hashCode結果一致,爲何要保證這一點呢,那就歸結到java中的那幾個基於Hash實現的集合上了,好比HashMap、HashSet等,這些集合須要用到對象的hash值來參與計算定位。
使用hashCode的目的就是爲了散列元素,最終元素可否散列均勻和hashCode的實現息息相關,即爲hash函數。code
hashCode的實現方式並非隨手而來的,須要考慮各類狀況,選擇合適的方式來實現,舉個例子,在Java的HashMap集合中,採用的就是鏈地址法來處理hash衝突。htm
參考:對象