一.爲什麼要重寫
Java中的超類Object類中定義的equals()方法是用來比較兩個引用所指向的對象的內存地址是否一致
Object類中equals()方法的源碼
public boolean equals(Object obj) {
return (this == obj);
}
********************************************************************
Object類中的hashCode()方法,用native關鍵字修飾,說明這個方法是個原生函數,也就說這個方法的實現不是用java語言實現的,是使用c/c++實現的,並且被編譯成了DLL,由java去調用,jdk源碼中不包含。對於不同的平臺它們是不同的,java在不同的操作系統中調用不同的native方法實現對操作系統的訪問,因爲java語言不能直接訪問操作系統底層,因爲它沒有指針。
這種方法調用的過程:
1、在java中申明native方法,然後編譯
2、用javah產生一個 .h 文件
3、寫一個 .cpp文件實現native導出方法,其中需要包含第二步產生的.h文件(其中又包含了jdk帶的jni.h文件);
4、將.cpp文件編譯成動態鏈接庫文件
5、在java中用System.loadLibrary()文件加載第四步產生的動態鏈接庫文件,然後這個navite方法就可被訪問了
Java的API文檔對hashCode()方法做了詳細的說明,這也是我們重寫hashCode()方法時的原則【Object類】
重點要注意的是:
a. 在java應用程序運行時,無論何時多次調用同一個對象時的hsahCode()方法,這個對象的hashCode()方法的返回值必須是相同的一個int值
b. 如果兩個對象equals()返回值爲true,則他們的hashCode()也必須返回相同的int值
c. 如果兩個對象equals()返回值爲false,則他們的hashCode()返回值也必須不同
public native int hashCode();
現在到了說正題了,爲什麼要重寫
我們在定義類時,我們經常會希望兩個不同對象的某些屬性值相同時就認爲他們相同,所以我們要重寫equals()方法,按照原則,我們重寫了equals()方法,也要重寫hashCode()方法,要保證上面所述的b,c原則;所以java中的很多類都重寫了這兩個方法,例如String類,包裝類
什麼情況下需要重寫hashCode()方法和equals()方法:
當我們自定義的一個類,想要把它的實例保存在集合中時,我們就需要重寫這兩個方法;集合(Collection)有兩個類,一個是List,一個是Set
List:集合中的元素是有序的,可以重複的
Set:無序,不可重複的
以HashSet來說明:
HashSet存放元素時,根據元素的hashCode值快速找到要存儲的位置,如果這個位置有元素,兩個對象通過equals()比較,如果返回值爲true,則不放入;如果返回值爲false,則這個時候會以鏈表的形式在同一個位置上存放兩個元素,這會使得HashSet的性能降低,因爲不能快速定位了。還有一種情況就是兩個對象的hashCode()返回值不同,但是equals()返回true,這個時候HashSet會把這兩個對象都存進去,這就和Set集合不重複的規則相悖了;所以,我們重寫了equals()方法時,要按照b,c規則重寫hashCode()方法!
二.如何重寫
比較兩個Java對象時,
我們需要覆蓋equals和
hashCode。
在比較結果時:
下面我們將介紹幾種常用方法:
1.經典方式
這種17和31散列碼的想法來自經典的Java書籍——《Effective
Java》第九條。下面我們來看看是如何實現的...
2.JDK 7
對於JDK7及更新版本,你可以是使用java.util.Objects
來重寫 equals 和 hashCode 方法,代碼如下
java.util.Objects
來重寫 equals 和 hashCode 方法,代碼如下3.Apache Commons Lang
或者,您可以使用Apache
Commons LangEqualsBuilder
和HashCodeBuilder
方法。代碼如下
EqualsBuilder
和HashCodeBuilder
方法。代碼如下最後測試總結:
在使用上述三種任何一種方式都可以到如下結果:
其實後兩種都是對於17和31散列碼思想的封裝實現。具體請參考《Effective Java》第九條。
整理自:http://blog.csdn.net/jing_bufferfly/article/details/50868266
其實後兩種都是對於17和31散列碼思想的封裝實現。具體請參考《Effective Java》第九條。
http://blog.csdn.net/zzg1229059735/article/details/51498310