重寫hashcode和equals方法

最近在看jvm優化的原理,不知不覺就看到引用和指針上的區別了,再然後就看了hash(散列)算法的實現思路,越看越不着邊際,好吧,言歸正傳。

Java裏面比較對象相等,有兩種方式,一種是使用==號,另一種是使用equals方法。

==號:
判斷兩個對象的內存地址是否相等,相等則爲同一個對象,不相等則不是,
對於基本類型數據,則只判斷兩個值是否相同。
equals方法:
Object類默認都實現了equals方法和hashcode方法,首先看一下equals方法的源碼
equals源碼
object默認判斷相等也是用的==號,即兩個對象的內存地址是否相同。

有時候我們可能只需要兩個對象的屬性值相同,就認爲這兩個對象是同一個對象,或者我們只是比較對象的屬性是否相同,而不需要判斷內存地址是否相同,因爲判斷內存地址相同比消耗資源,這個時候我們就需要重寫equals方法,比如String類默認就重寫了equals方法,該方法默認就只判斷內容是否相同。
這裏寫圖片描述
首先判斷內存地址是否相同,如果相同直接返回true,如果不相同,則判斷內容是否相同。

hashcode方法:
Object默認實現了該方法,使用native修飾符,調用本地接口實現。
這裏寫圖片描述
Java api對該方法的描述:
返回該對象的哈希碼值。支持此方法是爲了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。
hashCode 的常規協定是:

在 Java 應用程序執行期間,在對同一對象多次調用 hashCode 方法時,必須一致地返回相同的整數,前提是將對象進行 equals 比較時所用的信息沒有被修改。從某一應用程序的一次執行到同一應用程序的另一次執行,該整數無需保持一致。
一句話:返回的是在jvm中的僞地址,並不是真實的地址,但可以認爲是真實的,因爲不同的對象僞地址都會不同。
使用該方法的目的是在使用諸如Hashtable、HashSet、HashMap的時候,提搞HashMap存儲對象的效率。

此時,equals方法和hashcode方法是相互獨立的,並沒有什麼關係。
但在使用HashMap進行存儲對象時,會判斷對象的hash值和equals方法來決定是否已有對象存入HashMap中,看源碼:
這裏寫圖片描述

所以根據業務需要可能會重寫Object的equals方法,但如果要把該對象放入HashMap、HashSet中,爲了提高效率以及準確性,還需要重寫Hashcode方法,因爲Java規定:
equals方法相同,hashcode值必須相同,
equals方法不相同,hashcode值必須不相同,
這樣才能確定該對象的唯一性。
toString方法:
Object默認實現是調用的Object的hashcode方法,可以看下源碼,這裏就不貼圖了,System.out.print(obj)默認調用的是String的String.valueOf(obj)方法,而valueOf方法調用的又是該對象的toString方法,如果不重寫toString方法的話,默認會調用Object的toString方法,所以個人感覺重寫toString方法只是爲了調試用的,比如打印對象的屬性信息。現在一般都是debug了,感覺可重寫,也可以不重寫。
寫的不好,歡迎指正。

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