深入理解equals和hashCode關系和區別

深入理解equals和hashCode關系和區別

  • 直入主題:
    • 區別:
      • 1.他們判斷對象相同的方式不一樣:
      • 2.他們判斷對象是否相等的準確率不一樣:
    • 改寫equals時總是要改寫hashcode
    • 分享一波:程序員賺外快-必看的巔峰干貨

為什么要說equals和hashCode這兩個東西,一來是因為有不少小伙伴面試時被問過這個東西,二來則是因為如果了解了這兩個東西的原理,那么實際的開發過程中,對效率和容錯率上還是能幫上很大的忙!

直入主題:

很多人把他們放在一起比較,那我們首先要想到的是,他們肯定有大致相同的作用,和一些細小的區別。
先說說他們相同的作用:equals和hashCode方法都是用來判斷兩個對象的值是否相等,請記住這里說的相等僅僅說的是兩個對象的值,和他們的引用無關

區別:

1.他們判斷對象相同的方式不一樣:

2.他們判斷對象是否相等的準確率不一樣:

為啥這樣說,因為hashCode有極小概率會判斷錯,而equals的判斷結果是百分百正確的

相信看到這里已經有朋友有疑問了,既然hashCode方法不能準確判斷,那我們為什么還要用它?哈哈哈,因為我們無法忍受丟棄他的另一個優點,就是效率高,接著往下看,我們慢慢捋一捋。

先說上面的第一點:判斷對象的相等的方式不一樣

1.equals:重寫的equals方法,比如String 的equals方法,如圖:
在這里插入圖片描述
他最終的目的循環判斷兩個對象的每一個字符是否相等,所有字符全部對應相等,那他們的值肯定也就相等了,這是equals的判斷方法

hashCode的判斷方法:hashCode是通過用hash算法來計算具體對象實例,得到斌返回一個hashcode值。通過比較hashcode值是否相等來判斷兩個對象是否相等,

相信大家看到這里是已經有點懵逼了,別急,接下來具體講講他的原理:

以java.lang.Object來理解,JVM每new一個Object,它都會將這個Object丟到一個Hash哈希表中去,這樣的話,下次做Object的比較或者取這個對象的時候,它會根據對象的hashcode再從Hash表中取這個對象。這樣做的目的是提高取對象的效率。具體過程是這樣:

  1. new Object(),JVM根據這個對象的Hashcode值,放入到對應的Hash表對應的Key上,如果不同的對象確產生了相同的hash值,也就是發生了Hash key相同導致沖突的情況,那么就在這個Hash key的地方產生一個鏈表,將所有產生相同hashcode的對象放到這個單鏈表上去,串在一起。
  2. 比較兩個對象的時候,首先根據他們的hashcode去hash表中找他的對象,當兩個對象的hashcode相同,那么就是說他們這兩個對象放在Hash表中的同一個key上,那么他們一定在這個key上的鏈表上。那么此時就只能根據Object的equal方法來比較這個對象是否equal。當兩個對象的hashcode不同的話,肯定他們不能equal.

可能經過上面理論的講一下大家都迷糊了,我也看了之后也是似懂非懂的。下面我舉個例子詳細說明下。

list是可以重復的,set是不可以重復的。那么set存儲數據的時候是怎樣判斷存進的數據是否已經存在。使用equals()方法呢,還是hashcode()方法。
  假如用equals(),那么存儲一個元素就要跟已存在的所有元素比較一遍,比如已存入100個元素,那么存101個元素的時候,就要調用equals方法100次。
  
  但如果用hashcode()方法的話,他就利用了hash算法來存儲數據的。
這樣的話每存一個數據就調用一次hashcode()方法,得到一個hashcode值及存入的位置。如果該位置不存在數據那么就直接存入,否則調用一次equals()方法,不相同則存,相同不存。這樣下來整個存儲下來不需要調用幾次equals方法,雖然多了幾次hashcode方法,但相對于前面來講效率高了不少。

上面開始的時候我著重說了重寫的equals方法,為什么要重寫呢?

因為Object的equal方法默認是兩個對象的引用的比較,意思就是指向同一內存,地址則相等,否則不相等;如果你現在需要利用對象里面的值來判斷是否相等,則重載equal方法。

說道這個地方我相信很多人會有疑問,相信大家都被String對象的equals()方法和"= ="糾結過一段時間,當時我們知道String對象中equals方法是判斷值的,而= =是地址判斷。
那照這么說equals怎么會是地址的比較呢?

那是因為實際上JDK中,String、Math等封裝類都對Object中的equals()方法進行了重寫。
  我們先看看Object中equals方法的源碼:
  在這里插入圖片描述
  我們都知道所有的對象都擁有標識(內存地址)和狀態(數據),同時“==”比較兩個對象的的內存地址,所以說使用Object的equals()方法是比較兩個對象的內存地址是否相等,即若object1.equals(object2)為true,則表示equals1和equals2實際上是引用同一個對象。雖然有時候Object的equals()方法可以滿足我們一些基本的要求,但是我們必須要清楚我們很大部分時間都是進行兩個對象的比較,這個時候Object的equals()方法就不可以了,所以才會有String這些類對equals方法的改寫,依次類推Double、Integer、Math。。。。等等這些類都是重寫了equals()方法的,從而進行的是內容的比較。希望大家不要搞混了。

改寫equals時總是要改寫hashcode

java.lnag.Object中對hashCode的約定:

  1. 在一個應用程序執行期間,如果一個對象的equals方法做比較所用到的信息沒有被修改的話,則對該對象調用hashCode方法多次,它必須始終如一地返回同一個整數。
  2. 如果兩個對象根據equals(Object o)方法是相等的,則調用這兩個對象中任一對象的hashCode方法必須產生相同的整數結果。
  3. 如果兩個對象根據equals(Object o)方法是不相等的,則調用這兩個對象中任一個對象的hashCode方法,不要求產生不同的整數結果。但如果能不同,則可能提高散列表的性能。
    根據上一個問題,實際上我們已經能很簡單的解釋這一點了,比如改寫String中的equals為基于內容上的比較而不是內存地址的話,那么雖然equals相等,但并不代表內存地址相等,由hashcode方法的定義可知內存地址不同,沒改寫的hashcode值也可能不同。所以違背了第二條約定。
    又如new一個對象,再new一個內容相等的對象,調用equals方法返回的true,但他們的hashcode值不同,將兩個對象存入HashSet中,會使得其中包含兩個相等的對象,因為是先檢索hashcode值,不等的情況下才會去比較equals方法的。

原創文章,轉載請標明出處

分享一波:程序員賺外快-必看的巔峰干貨

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:
http://www.pswp.cn/news/537063.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/537063.shtml
英文地址,請注明出處:http://en.pswp.cn/news/537063.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

lol韓服游戲內設置_韓服LOL進去了還不能玩?教你如何玩韓服!

領取免費韓服LOL安全號,百度搜索韓服LOL微博關注即可!上圖錯誤為常識性錯誤,LOL韓服游戲的安裝文件路徑有中文所導致的錯誤 解決方法:將安裝路徑里的中文改成英文即可 舉例 包含中文漢字的文件夾都是錯誤的 Program FilesLOL韓服 …

Jdk 和 jre 的 關系和區別

Jdk 和 jre 的 關系和區別 區別: JDK:是Java Development Kit 的簡稱–>翻譯過來就是:Java 開發工具包。是程序員使用java語言編寫java程序所需的開發工具包,是提供給程序員使用的。 JRE:是Java Runtime Environm…

OpenCV-Python入門教程7-PyQt編寫GUI界面

前面一直都是使用命令行運行代碼,不夠人性化。這篇用Python編寫一個GUI界面,使用PyQt5編寫圖像處理程序。包括:打開、關閉攝像頭,捕獲圖片,讀取本地圖片,灰度化和Otsu自動閾值分割的功能。 使用Qt Designer…

spark 廣播變量大數據_大數據處理 | Spark集群搭建及基本使用

點擊藍字關注我前面用了一篇文章詳細的介紹了集群HDFS文件系統的搭建,HDFS文件系統只是一個用于存儲數據的系統,它主要是用來服務于大數據計算框架,例如MapReduce、Spark,本文就接著上一篇文章來詳細介紹一下Spark集群的搭建及Spa…

如何將本地項目上傳到gitee

*************************************優雅的分割線 ********************************** 分享一波:程序員賺外快-必看的巔峰干貨 如果以上內容對你覺得有用,并想獲取更多的賺錢方式和免費的技術教程 請關注微信公眾號:HB荷包 一個能讓你學習技術和賺錢方法的公眾號,持續更…

oracle dg 備庫未設置convert參數導致ORA-01111,ORA-01110

2019獨角獸企業重金招聘Python工程師標準>>> 查看trace 文件: MRP0: Background Managed Standby Recovery process started (amls) started logmerger process Sun Jan 20 07:55:53 2019 Managed Standby Recovery starting Real Time Apply MRP0: Back…

git回退歷史版本無法上傳_Git系列教程(二):版本庫中添加文件、版本回退

Git系列教程(一):簡介、安裝、配置我們學習了分布式和版本控制系統的概念、Git具有的8個功能以及如何在Windows上安裝Git、進行相關配置并創建版本庫。Git版本庫中添加文件Git 的工作就是創建和保存你的項目的快照及與之后的快照進行對比。我們編寫一個readme.txt文…

nginx反向代理配置如何去除前綴

使用nginx做反向代理的時候,可以簡單的直接把請求原封不動的轉發給下一個服務。設置proxy_pass請求只會替換域名,如果要根據不同的url后綴來訪問不同的服務,則需要通過如下方法: 方法一:加"/"** server {l…

「作文素材詳解」寫作必知篇:語言優美不是作文第一要求

語言優美不是作文第一要求“教孩子寫作文,老師家長應該先提升自己。”“語言優美不是作文的第一要求。”“如果教孩子寫漂亮的違心話,會害了他一輩子。”日前,著名作家肖復興來到體育東路小學,與廣州的一線語文教師交流&#xff0…

華為安裝gsm框架_華為nova5怎么下載安裝谷歌服務助手,安裝GMS框架教程

看到不少的華為nova5用戶喜歡這個谷歌服務助手,也就是想安裝這個GMS框架,可是一直不知道如何下載安裝,這個谷歌服務框架是可以在系統軟件里面可以刪除的一個APK程序,但現在有很多的軟件和游戲需要谷歌服務的支持,那咱們…

VMware安裝虛擬機并使用NAT模式連接網絡

*************************************優雅的分割線 ********************************** 分享一波:程序員賺外快-必看的巔峰干貨 如果以上內容對你覺得有用,并想獲取更多的賺錢方式和免費的技術教程 請關注微信公眾號:HB荷包 一個能讓你學習技術和賺錢方法的公眾號,持續更…

PHPStudy下Apache SSL證書安裝教程

一、安裝SSL證書的環境 Apache安裝目錄:E:phpStudyPHPTutorialApache 以上為windows下測試SSL證書安裝的目錄,具體目錄請根據自己的實際環境! 二、獲取SSL證書 成功在沃通申請SSL證書后,會得到一個壓縮包文件,解壓后得到四個文件&…

laravel 集成采集_新版2020 Laravel采集網站程序

環境:php5.6數據庫:mysql5.5集成環境軟件:護衛神apache這套程序是520.ag 的網站很早的程序了是去年還是前年 應該是前年免費采集網站 但是經常掛 其實他網站掛和服務器沒有多大關系 是程序沒有作好優化這套程序可以大家做起來 自己用就可以了 放出去免費采集的話 網站容易死程…

詳解模板方法設計模式

分享一波:程序員賺外快-必看的巔峰干貨 概念 定義一個操作中的算法骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個算法的結構即可重定義該算法的重復代碼全部在父類里面,不同業務的,使用抽象方法,抽取給子類進…

怎么從已有文件中挑選需要的文字重新生成新文件_CAD問題全面解答(幾乎涵蓋了CAD使用的全部問題)...

1.【CTrlN無效時之解決辦法】眾所周知CTRLN是新建命令但有時候CTRLN則出現選擇面板這時只需到OP選項里調下設置操作:OP(選項)------系統-------右側有一個啟動(A顯示啟動對話框B不顯示啟動對話框)選擇A則新建命令有效,反則無效2.【Ctrl鍵無效之解決辦法】…

中國官方要求進一步加強中資商業銀行境外機構合規管理

中新社北京1月22日電 (記者 王恩博)為推動在境外設有經營性機構的中資商業銀行進一步優化集團合規管理體系,健全跨境合規管理機制,提高跨境合規管理有效性,實現境外機構安全穩健運行,中國銀保監會22日發布《關于加強中資商業銀行境…

詳解:設計模式之-代理設計

分享一波:程序員賺外快-必看的巔峰干貨 概念 通過代理控制對象的訪問,可以詳細訪問某個對象的方法,在這個方法調用處理,或調用后處理(類似于AOP)。 代理設計模式應用場景:AOP、權限控制、事務 常見代理的分類有&am…

【實時+排重】擺脫渠道統計刷量作弊行為

如今的渠道統計不僅要看精準度,更要看數據的真實性。 對App的推廣業務而言,渠道監測和統計是必不可少的環節,不論以什么形式開展推廣,終究都要具體落實到App的安裝量、激活量等指標上。但在如今數據刷量和作假行為橫行的背景下&am…

python清空idle的內容_Python IDLE清空窗口的實例

{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":4,"count":4}]},"card":[{"des":"阿里技術人對外發布原創技術內容的最大平臺&…