摘自http://tieba.baidu.com/f?kz=879340761
在某些時候,我們需要判斷兩個對象是否相等。Java的每個類都繼承於Object類。它使用equals()及hashCode()這兩個方法來判斷兩個Object是否相等。
1. equals()
需要滿足5點:
1 自省:對於任一非null引用x,x.equals(x)應返回true;
2 反射:對於任一非null引用x及y,僅在y.equals(x)返回true時,x.equals(y)才返回true;
3 傳遞:對於任一非null引用x、y及z,如果x.equals(y)為true,而且y.equals(z)為true,則x.equals(z)應返回true;
4 穩定:對於任一非null引用x及y,如果用於比較的資訊沒有改變,無論多少次調用x.equals(y)都會恒定地返回true或false;
5 對於任一非null引用x,x.equals(null)應返回false。
Object的預設實現是只要在兩個Object的引用相等時,才會返回true,即return x == y;
如果要覆蓋(override)此方法,需要同時覆蓋hasCode(),要求是:兩個相等的對象必須有相等的hash code。
2. hashCode()
其必須遵循的約定是:
1 如果對象equals, 則hashCode一定相等;
2 如果equals()返回false,這兩個對象的hashCode()可能相同。但不等的兩個對象返回不同的int值可以提高hashtables的運行效率。
作為常理,不相等的對象的hasCode()應可能地返回不同的int值。
3. 對象是否相等的規則
1 判斷兩個對象的hashCode是否相等; 如果不相等,認為兩個對象也不相等, 完畢.
2 如果相等, 再調用equals方法.
4. hashCode最大的用處是什麼呢?
Java中的集合(Collection)有兩類,一類是List,再有一類是Set。
你知道它們的區別嗎?前者集合內的元素是有序的,元素可以重複;後者元素無序,但元素不可重複。
那麼這裡就有一個比較嚴重的問題了:要想保證元素不重複,可兩個元素是否重複應該依據什麼來判斷呢?
這就是Object.equals方法了。但是,如果每增加一個元素就檢查一次,那麼當元素很多時,後添加到集合中的元素比較的次數就非常多了。
Java採用了雜湊表的原理, 雜湊演算法也稱為散列演算法,是將資料依特定演算法直接指定到一個地址上. 初學者可以這樣理解,hashCode方法實際上返回的就是Object Storage Service的物理地址(實際可能並不是)。
有了hashCode,當集合要添加新的元素時,先調用這個元素的hashCode方法,就一下子能定位到它應該放置的物理位置上。
如果這個位置上沒有元素,它就可以直接儲存在這個位置上,不用再進行任何比較了;如果這個位置上已經有元素了,
就調用它的equals方法與新元素進行比較,相同的話就不存了,不相同就散列其它的地址。
所以這裡存在一個衝突解決的問題。這樣一來實際調用equals方法的次數就大大降低了,幾乎只需要一兩次.
5. 為什麼在HIBERNA裡要重寫hashCode和equals這兩個方法?
在hibernate中,經常使用set集合來儲存相關對象,而set集合是不允許重複的, so, 道理同4.