Object類中hashCode()和equals()方法詳解(附圖)
下圖是規範中要求的:
圖解:比如equals相等的箭頭指向hashcode相等,標示equals相等那麼必有hashcode相等。另外有兩個箭頭指向別人的標示可能是其中之一。
//JAVA程式碼: public static void main(String[] args) { Object obj1 = new Object(); Object obj2 = new Object(); Object obj3 = obj2; System.out.println("obj1 equals obj2 ?" + obj1.equals(obj2)); System.out.println("obj2 equals obj3 ?" + obj2.equals(obj3)); System.out.println("obj1's hashcode: " + obj1.hashCode()); System.out.println("obj2's hashcode: " + obj2.hashCode()); System.out.println("obj2's hashcode: " + obj3.hashCode()); } } //輸出結果: obj1==obj2 ?false obj2==obj3 ?true obj1's hashcode: 12677476 obj2's hashcode: 33263331 obj3's hashcode: 33263331
也就是當我們寫了一個自己的class,然後用class new了兩個物件,如果在這兩個物件上用equals時,此時比較的兩個引用是不是一樣,也就是他們的實體地址是不是一樣,如果不一樣的話,就會返回false. 我們實際用的時候,往往不是希望比較兩個物件的實體地址是不是一樣,而比較兩個物件的屬性等東西是不是一樣,所以Object提供的方法往往不能滿足我們要求。 這就需要我們覆蓋Object的equals方法。
如果要覆蓋Object的equals的方法,一定要滿足以下幾個等價關係:
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)返回ture,那 麼x.equals(z)也必須返回true.
4. 一致性,對於任何非null的引用值x,y,只要equals比較操作的兩個物件中所用的資訊沒有被修改,多次 呼叫x.equals(y)就會一致的返回true,或者一致的返回false.
5.對於任何的非null的值x,x.equals(null),必須返回false .
如果我們的程式中沒有完全遵守這些約定,那麼你的程式就有可能發生問題。
沒有出問題的原因是,因為你的程式沒有地方 直接呼叫 或者 間接呼叫 equals方法。 什麼是直接呼叫equals ,什麼是間接呼叫equals呢? 直接呼叫equals方法就是說,你顯式的在你的程式中對你自己的寫的物件上面呼叫equals方法, 間接呼叫呢,用一簡單的例子來說,當我們平常會把一個些物件放到collection,為了不重複,我們有呼叫collection的contains方法,此時就間接呼叫了collection中物件的equals方法。
覆蓋了equals的類中,也必須覆蓋hashCode方法
簡單的結論:當物件類沒有不符合規範的override equals()和hashcode()方法的時候,兩個物件做比較
- 如果equals()比較相同,那麼hashcode()肯定相同。
- 如果hashcode()比較相同,那麼equals()不一定相同。
眾所周之,String 、Math、還有Integer、Double。。。。等這些封裝類重寫了Object中的equals()方法,讓它不再比較控制代碼(引用),而是比較物件中實際包含的整數的值,即比較的是內容。
而Object的equals()方法比較的是地址值。 一般來說,如果你要把一個類的物件放入容器中,那麼通常要為其重寫equals()方法,讓他們比較地址值而不是內容值。特別地,如果要把你的類的物件放入雜湊中,那麼還要重寫hashCode()方法;要放到有序容器中,還要重寫compareTo()方法。
為什麼要重寫hashCode方法? 我們應該先了解java判斷兩個物件是否相等的規則。 在java的集合中,判斷兩個物件是否相等的規則是:
首先,判斷兩個物件的hashCode是否相等 如果不相等,認為兩個物件也不相等 如果相等,則判斷兩個物件用equals運算是否相等 如果不相等,認為兩個物件也不相等 如果相等,認為兩個物件相等
我們在equals方法中需要向下轉型,效率很低,所以先判斷hashCode方法可以提高效率。
equals()相等的兩個物件,hashcode()一定相等; equals()不相等的兩個物件,卻並不能證明他們的hashcode()不相等。換句話說,equals()方法不相等的兩個物件,hashcode()有可能相等。(我的理解是由於雜湊碼在生成的時候產生衝突造成的)。
反 過來:hashcode()不等,一定能推出equals()也不等;hashcode()相等,equals()可能相等,也可能不等。
相關推薦
Object類中hashCode()和equals()方法詳解(附圖)
下圖是規範中要求的: 圖解:比如equals相等的箭頭指向hashcode相等,標示equals相等那麼必有hashcode相等。另外有兩個箭頭指向別人的標示可能是其中之一。 //JAVA程式碼: public static void main
HashCode()和equals()方法詳解
這兩個方法的問題一直困擾了我很久。不清楚他們各自的用處和實現,記得在實習的時候遇到過一個問題:將自定義的物件放在一個set集合中,目的是篩選出不重複的物件集合,但是結果卻是錯誤的。比如說有10個物件,但是其中有兩個是相等的,那麼期望的set的大小應該是9,但是最終結果卻是10。讓我很奇怪,後來帶我的
JAVA hashCode和equals方法詳解
hashCode和equals方法都是Object基類的方法 先看一個例子 public class Studeng { private Integer sid; private String name; public
Java 中hashCode()和equals()方法
Java中,涉及到兩個物件的比較時,我們會用到hashCode()和equals()。這兩個方法是Object類中定義的方法。 1. api中的描述 (1)hashCode() hashCode()方法給物件返回一個hash code值。這個方法被用於hash tables,
hashset中hashcode和equals方法
equals和hashcode 在hashset中,加入元素先判斷兩個物件的hashcode是否相等,在判斷equals是否相等,以為equals效率低,用hashcode判斷可以減少equals的呼叫次數,增加效率。物件的equals方法如果沒重寫預設繼承object,o
前端學習筆記之js中apply()和call()方法詳解
經過網上的大量搜尋,漸漸明白了apply()和call方法的使用,為此寫一篇文章記錄一下。 定義 apply()方法: Function.apply(obj,args)
python和mysql互動詳解---- (pandas)讀csv檔案,executemny批量寫入db中
主要用到pandas從csv檔案中抓資料,pandas抓出的資料是dataframe格式的,而且有的可能是Nan,抓出df格式的資料需要再處理,才能批處理的寫入資料庫中,executemany批出的格式不能是df,這裡處理成list import pymysql import codec
抽象類和介面的詳解(例項)
抽象類和介面在我們的程式碼中,生活中息息相關,與上圖所示,操縱複雜,密切相關,那麼問題來了,何謂抽象類,何謂介面? 帶著這層薄紗,慢慢揭開這層薄紗;也許在古代,新婚之夜,透過這層薄紗,你看到的或者是驚喜,或許是驚悚,不要怕,無論是驚悚還是驚喜,她都會伴你一
Android Studio中Git和GitHub使用詳解(上篇)
一、Git和GitHub簡述 1.Git 分散式版本控制系統,最先使用於Linux社群,是一個開源免費的版本控制系統,功能類似於SVN和CVS。Git與其他版本管理工具最大的區別點和優點就是分散式; git是採用分散式版本庫機制,不需要每次都將檔案推送到版本控制伺服
Android中的Intent和Intent-Filter詳解(二)
Data、Type屬性與intent-filter配置 Data屬性接收一個Uri物件作為其值,Uri物件類似於“content://com.android.contacts/contacts/#”,關於Uri的相關知識大家可以自行搜尋。 Data屬性通常
Android中的Intent和Intent-Filter詳解(一)
Intent對於Android應用的作用 Intent,翻譯過來是“意圖”,它是對Android應用程式“意圖”的封裝。例如ActivityA想啟動ActivityB,那麼“想啟動Activit
2020了你還不會Java8新特性?方法引用詳解及Stream 流介紹和操作方式詳解(三)
方法引用詳解 方法引用: method reference 方法引用實際上是Lambda表示式的一種語法糖 我們可以將方法引用看作是一個「函式指標」,function pointer 方法引用共分為4類: 類名::靜態方法名 引用名(物件名)::例項方法名 類名::例項方法名 (比較不好理解,個地方呼叫的方
解析xml的4種方法詳解(轉)
項目 目標 源碼 更多 news 大量 優秀 大型 頻繁 http://blog.csdn.net/jzhf2012/article/details/8532873 1. 介紹 1)DOM(JAXP Crimson解析器) DOM是用與平臺和語言無關的方式表
Spring Boot中使用MyBatis註解配置詳解(1)
sql type .org 實體 sch 整合 PE 匯總 同傳 之前在Spring Boot中整合MyBatis時,采用了註解的配置方式,相信很多人還是比較喜歡這種優雅的方式的,也收到不少讀者朋友的反饋和問題,主要集中於針對各種場景下註解如何使用,下面就對幾種常見的情況舉
H 264的兩個概念 DC係數和AC係數 MV預測過程詳解(附圖)
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
ES6中export default 命令的詳解(引用)
我們知道在學習VUE的時候export default{}是不可缺少的,但是它的含義我們必須理解。 export default{}這是在複用元件的時候用到的。假設我們寫了一個單頁面元件 A 檔案,而在另一個檔案 B 裡面需要用到它,那麼就要用 ES6 的 import/export 語法
Quartz學習——Spring和Quartz整合詳解(三)
Spring是一個很優秀的框架,它無縫的集成了Quartz,簡單方便的讓企業級應用更好的使用Quartz進行任務的排程。下面就對Spring整合Quartz進行簡單的介紹和示例講解!和上一節 Quartz學習——2、簡單入門示例Demo 的流程相似,介紹Spring和Quar
Swagger使用方法詳解(WebApi)——看完不會用你打我
WebApi介面開發完畢後,交付給前端人員或手機端開發者時介面說明文件是必不可少的配套裝置,如果公司流程不規範大家使用口口相傳的交接方式,而且沒有改進的慾望,那你可以到此為止了。Swagger是方便測試介面,快速展示註釋內容,生成Restful風格介面文件的框架。 Swag
Quartz學習——SSMM(Spring+SpringMVC+Mybatis+Mysql)和Quartz整合詳解(四)
當任何時候覺你得難受了,其實你的大腦是在進化,當任何時候你覺得輕鬆,其實都在使用以前的壞習慣。 通過前面的學習,你可能大致瞭解了Quartz,本篇博文為你開啟學習SSMM+Quartz的旅程!歡迎上車,開始美好的旅程! 本篇是在SSM框架——Spri
爬蟲資料提取方法詳解(一)
爬蟲中資料的分類:結構化資料(json,xml等)處理方式是直接轉化為python型別,jsonpath,xpath,bs4等. 非結構化資料(HTML)處理方式是正則表示式,xpath,bs4等. 資料提取