java為什么要重寫hashCode和equals方法

如果不被重寫(原生)的hashCode和equals是什么樣的?
  1. ? ? ? 不被重寫(原生)的hashCode值是根據內存地址換算出來的一個值。
  2. ? ? ? 不被重寫(原生)的equals方法是嚴格判斷一個對象是否相等的方法(object1 == object2)。
? 為什么需要重寫equals和hashCode方法?
? ? ? 在我們的業務系統中判斷對象時有時候需要的不是一種嚴格意義上的相等,而是一種業務上的對象相等。在這種情況下,原生的equals方法就不能滿足我們的需求了
? ? ? 所以這個時候我們需要重寫equals方法,來滿足我們的業務系統上的需求。那么為什么在重寫equals方法的時候需要重寫hashCode方法呢?
? ? ? 我們先來看一下Object.hashCode的通用約定(摘自《Effective Java》第45頁)
  1. ? ? 在一個應用程序執行期間,如果一個對象的equals方法做比較所用到的信息沒有被修改的話,那么,對該對象調用hashCode方法多次,它必須始終如一地返回 同一個整數。在同一個應用程序的多次執行過程中,這個整數可以不同,即這個應用程序這次執行返回的整數與下一次執行返回的整數可以不一致。
  2. ? ? 如果兩個對象根據equals(Object)方法是相等的,那么調用這兩個對象中任一個對象的hashCode方法必須產生同樣的整數結果。
  3. ? 如果兩個對象根據equals(Object)方法是不相等的,那么調用這兩個對象中任一個對象的hashCode方法,不要求必須產生不同的整數結果。然而,程序員應該意識到這樣的事實,對于不相等的對象產生截然不同的整數結果,有可能提高散列表(hash table)的性能。
? ? ?如果只重寫了equals方法而沒有重寫hashCode方法的話,則會違反約定的第二條:相等的對象必須具有相等的散列碼(hashCode)
? ? ?同時對于HashSet和HashMap這些基于散列值(hash)實現的類。
HashMap的底層處理機制是以數組的方法保存放入的數據的(Node<K,V>[] table),其中的關鍵是數組下標的處理。數組的下標是根據傳入的元素hashCode方法的返回值再和特定的值異或決定的如果該數組位置上已經有放入的值了,且傳入的鍵值相等則不處理,若不相等則覆蓋原來的值,如果數組位置沒有條目,則插入,并加入到相應的鏈表中。檢查鍵是否存在也是根據hashCode值來確定的。所以如果不重寫hashCode的話,可能導致HashSet、HashMap不能正常的運作、
? 如果我們將某個自定義對象存到HashMap或者HashSet及其類似實現類中的時候,如果該對象的屬性參與了hashCode的計算,那么就不能修改該對象參數hashCode計算的屬性了。有可能會移除不了元素,導致內存泄漏。

? 擴展:
? ? ? 在重寫equals方法的時候,需要遵守下面的通用約定:
? ? ? ? ? ?1、自反性。
? ? ? ? ? ? ? ?對于任意的引用值x,x.equals(x)一定為true。
? ? ? ? ? ?2、對稱性。
? ? ? ? ? ? ? ?對于任意的引用值x和y,當且僅當y.equals(x)返回true時,x.equals(y)也一定返回true。
? ? ? ? ? ?3、傳遞性。
? ? ? ? ? ? ? ?對于任意的引用值x、y和z,如果x.equals(y)返回true,并且y.equals(z)也返回true,那么x.equals(z)也一定返回true。
? ? ? ? ? ?4、一致性。
? ? ? ? ? ? ? ?對于任意的引用值x和y,如果用于equals比較的對象沒有被修改的話,那么,對此調用x.equals(y)要么一致地返回true,要么一致的返回false。
? ? ? ? ? ?5、對于任意的非空引用值x,x.equals(null)一定返回false。
? ? ?重寫hashCode方法的大致方式:
? ? ? ? ? ? a、把某個非零常數值,比如說17(最好是素數),保存在一個叫result的int類型的變量中。
? ? ? ? ? ? b、對于對象中每一個關鍵域f(值equals方法中考慮的每一個域),完成一些步驟:
? ? ? ? ? ? ? ? 1、為該域計算int類型的散列嗎c:
? ? ? ? ? ? ? ? ? ? 1)、如果該域是boolean類型,則計算(f?0:1)。
? ? ? ? ? ? ? ? ? ? 2)、如果該域是byte、char、short或者int類型,則計算(int)f。
? ? ? ? ? ? ? ? ? ? 3)、如果該域是float類型,則計算Float.floatToIntBits(f)。
? ? ? ? ? ? ? ? ? ? 4)、如果該域是long類型,則計算(int)(f ^ (f>>>32))。
? ? ? ? ? ? ? ? ? ? 5)、如果該域是double類型,則計算Double.doubleToLongBits(f)得到一個long類型的值,然后按照步驟4,對該long型值計算散列值。
? ? ? ? ? ? ? ? ? ? 6)、如果該域是一個對象引用,并且該類的equals方法通過遞歸調用equals的方式來比較這個域,則同樣對這個域遞歸調用hashCode。如果要求一個更為復雜的比較,則為這個域計算一個“規范表示”,然后針對這個范式表示調用hashCode。如果這個域的值為null,則返回0(或者其他某個常數)
? ? ? ? ? ? ? ? ? ? 7)、如果該域是一個數組,則把每一個元素當做單獨的域來處理。也就是說,遞歸地應用上述規則,對每個重要的元素計算一個散列碼,然后根據步驟下面的做法把這些散列值組合起來。
? ? ? ? ? ? ? ? 2、按照下面的公式,把步驟1中計算得到的散列碼C組合到result中:
? ? ? ? ? ? ? ? ? ? result = 31*result+c。
? ? ? ? ? ? c、返回result。
? ? ? ? ? ? d、寫完hashCode方法之后,問自己“是否相等的實例具有相等的散列碼”。如果不是的話,找出原因,并修改。
? ? ? ? ? ? 可以通過org.apache.commons.lang.builder.HashCodeBuilder這個工具類來方便的重寫hashCode方法。

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

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

相關文章

stl中map函數_map :: max_size()函數,以及C ++ STL中的Example

stl中map函數C STL映射:: max_size() (C STL map::max_size() ) It returns the maximum number of elements the container(map) is able to hold but at runtime, the size of the container may be limited to a value smaller than specified by max_size() by the amount…

arduino 藍牙示例_Arduino簡單實例之八_藍牙模塊

1) 說明&#xff1a;藍牙模塊用于和手機或其它帶藍牙的設備通訊。藍牙設備分為主從兩種模式&#xff0c;作為主設備時&#xff0c;它查找和連接其它設備&#xff1b;作為從設備時只能被只它設備連接&#xff1b;通訊模式分透明傳輸和AT命令模式。最好購買主從一體的藍牙模…

zabbix使用JMX監控tomcat

JMX 全稱是Java Management Extensions,即Java管理擴展。Java程序會開放一些端口&#xff0c;用來獲取運行狀況。 從Zabbix2.0開始&#xff0c;內置了監控JMX的功能,叫做"Zabbix Java Gateway ",在Zabbix Serve上會啟動名為"Zabbix Java Gateway "的進程&…

自定義控件添加屬性_|AutoCAD LT 2019 Mac自定義功能區的方法

AutoCAD LT是一款非常好用的CAD三維設計繪圖軟件&#xff0c;最新版本2019擁有改進的桌面、新應用實現跨設備工作流&#xff0c;以及DWG比較等新功能&#xff0c;并且AutoCAD LT 2019 Mac可以根據你的需要和工作習慣來自定義功能區&#xff0c;下面為大家帶來自定義功能區的詳細…

操作系統中的文件系統和訪問方法

文件 (File) A file is basically a sequence of bytes organized into blocks that are understandable by any machines. In other words, the collection of related information that is stored in a secondary storage device is also called a file. The file is a colle…

centos7鏡像加速_docker 鏡像加速CentOS7詳細介紹

前言在Docker Hub官網上注冊帳號&#xff0c;即可下載使用倉庫里的全部的docker鏡像。而因為網絡原因&#xff0c;國內的開發者沒辦法流暢的下載鏡像&#xff0c;經常會出現下載中斷的錯誤。解決方法就是使用國內的容器Hub加速服務&#xff0c;本質就是更改pull優先級較高的服務…

java 根據類名示例化類_Java LocalDateTime類| atOffset()方法與示例

java 根據類名示例化類LocalDateTime類atOffset()方法 (LocalDateTime Class atOffset() method) atOffset() method is available in java.time package. atOffset()方法在java.time包中可用。 atOffset() method is used to create an OffsetDateTime to merge this LocalDat…

Zabbix監控——proxy 分布式監控配置

proxy分布式監控 Zabbix proxy是在大規模分布式監控場景中&#xff0c;采用的一種用以分擔server端壓力的分層結構&#xff0c; proxy可以代替zabbix server檢索客戶端的數據&#xff0c;然后把數據匯報給zabbix server&#xff0c;極大的減輕了server的負載壓力&#xff0c;使…

AutoCAD_acadiso.dwt卡死

2019獨角獸企業重金招聘Python工程師標準>>> 問題描述&#xff1a;每次執行到打開acadiso.dwt就卡死&#xff0c;且電腦顯示有網&#xff0c;確打不開網頁 可能原因&#xff1a;可能是因為AotuCAD是盜版的 解決辦法&#xff1a; 1.在任務管理器中把WSCommCntr.exe進…

else 策略模式去掉if_java – 用狀態/策略模式替換if/else邏輯

我認為你應該使用GoF模式Chain of responsibility.你應該引入兩個接口&#xff1a;1)你將檢查正確條件的條件,例如“如果zip文件不存在”并返回布爾結果 – 如果條件滿足則返回“true”,否則“else”,2)執行策略,它將運行分配有條件的動作,例如&#xff1a; “從指定的URL下載它…

docker簡介與搭建

1 . 對docker的理解&#xff1a; Docker 是一個開源的應用容器引擎&#xff0c;讓開發者可以打包他們的應用以及依賴包到一個可移植的鏡像中&#xff0c;然后發布到任何流行的 Linux或Windows 機器上&#xff0c;也可以實現虛擬化。容器是完全使用沙箱機制&#xff0c;相互之間…

Java BigInteger類| toByteArray()方法與示例

BigInteger類testBit()方法 (BigInteger Class testBit() method) testBit() method is available in java.math package. testBit()方法在java.math包中可用。 testBit() method is used to convert this BigInteger to a byte [] that holds 2s complement denotation of thi…

007_Web to lead

轉載于:https://www.cnblogs.com/bandariFang/p/6229491.html

設置header_Nginx的這些安全設置,你都知道嗎?

Nginx 是最流行的 Web 服務器&#xff0c;可以只占用 2.5 MB 的內存&#xff0c;卻可以輕松處理 1w 的 http 請求。做為網站的入口&#xff0c;Nginx 的安全設置重要性不言而喻。下面帶你一起去認識一下這些安全配置吧&#xff01;nginx.conf是 Nginx 最主要的配置文件&#xf…

動態路由協議_動態路由協議的類別

動態路由協議Dynamic routing protocols have been divided into 2 categories i.e Distance vector protocols and Link state protocols. Both of these protocols are being explained in detail in this tutorial. 動態路由協議分為距離矢量協議和鏈路狀態協議兩大類 。 本…

docker鏡像創建與優化

1 . 創建鏡像 有兩種方法構建鏡像&#xff1a; docker commit &#xff1a;將運行的容器保存成鏡像Dockerfile&#xff1a;自動構建 使用docker commit 創建鏡像分為三步&#xff1a; 運行容器修改容器將容器保存為鏡像 舉例&#xff1a; [rootdocker ~]# docker load -i…

ISP運營商實驗室測試機架拓撲搭建經驗分享

大家好&#xff0c;有些日子沒更新干貨了&#xff0c;近期難得有假期進行修整&#xff0c;思前顧后還是坐下來聊聊自己長期負責維護和搭建的實驗室環境。廢話不多說&#xff0c;直接上圖。因為圖較大&#xff0c;分上下部分進行上傳。網絡主框架&#xff08;上&#xff09;服務…

關于二手交易用戶指南怎么寫_讓用戶拍案叫絕文案怎么寫?試試這3個方法

“共鳴”到底是什么&#xff1f; 為什么有些文章會引起共鳴&#xff0c;而有些則沒有。現在假設為產品家用手持式美容儀寫一份副本。 由于主要重點是“家庭使用”&#xff0c;因此您立即想到了“家庭美容”的口號。 盡管這句話很簡單易懂&#xff0c;但談論起來總是很簡單……似…

結構化程序goto語句_C ++ goto語句| 查找輸出程序| 套裝1

結構化程序goto語句Program 1: 程序1&#xff1a; #include <iostream>#include <math.h>using namespace std;int main(){int num1 1;int num2 0;MY_LABEL:num2 num1 * num1;cout << num2 << " ";num1 num1 pow(2, 0);if (num1 < …

docker倉庫搭建、加密、用戶認證

1 . 含義及理解&#xff1a; 倉庫分為公開倉庫&#xff08;Public&#xff09;和私有倉庫&#xff08;Private&#xff09;兩種形式。最大的公開倉庫是 Docker Hub&#xff0c;存放了數量龐大的鏡像供用戶下載。 國內的公開倉庫包括 Docker Pool等&#xff0c;可以提供大陸用戶…