float foo=42e1為什么錯_為什么重寫了equals()也要重寫hashCode()

小Hub領讀:

雖然是很基礎的一篇文章,但是對于equals、hashcode兩個方法,相信很多人都與其中的規則不熟悉,來跟著小Hub花個8分鐘回顧一下!


作者:不學無數的程序員

https://my.oschina.net/u/4030990/blog/3134199

在?EffectiveJava中第九條規定在覆蓋?equals()方法時總要覆蓋?hashCode()方法。這是為什么呢?接下來我們就介紹一下這兩個方法。

Java中的?equals()方法和?hashCode()方法都是在?Object類中的方法,而在Java中所有的類都是?Obejct類的子類,所以Java中所有的方法都會有這兩個方法的默認實現。

equals方法

Object類中的?equals()方法定義如下

public boolean equals(Object obj) {

return (this == obj);

}

我們發現在?equals()方法中就關鍵的?==,那么?==在Java中有什么含義呢,我們都知道在Java中分為基本數據類型和引用數據類型。那么?==在這兩個類型中作用是不一樣的。

  • 基本數據類型:比較的是?==兩邊值是否相等

  • 引用數據類型:比較的是?==兩邊內存地址是否相等

基本數據類型包括:?byte,?short,?char,?int,?long,?float,?double,?boolean

而通過Java文檔中的?equals()方法描述,所有要實現自己的?equals()方法都要遵守下面幾個規則

  • 自反性:對于任何對象x,?x.equals(x)應該返回?true

  • 對稱性:對于任何兩個對象x和y,如果?x.equals(y)返回?true,那么?y.equals(x)也應該返回?true

  • 傳遞性:對于多個對象x,y,z,如果?x.equals(y)返回?true,?y.equals(z)返回?true,那么?y.equals(z)也應該返回?true

  • 一致性:對于兩個非空對象x,y,在沒有修改此對象的前提下,多次調用返回的結果應該相同

  • 對于任何非空的對象x,?x.equals(null)都應該返回?false

hashCode方法

Object中的?hashCode()方法是一個本地方法,返回一個?int類型的哈希值。

public native int hashCode();

在?hashCode()方法中也有一些規約

  • 如果對象在使用?equals方法中進行比較的參數沒有修改,那么多次調用一個對象的?hashCode()方法返回的哈希值應該是相同的。

  • 如果兩個對象通過?equals方法比較是相等的,那么要求這兩個對象的?hashCode方法返回的值也應該是相等的。

  • 如果兩個對象通過?equals方法比較是不同的,那么也不要求這兩個對象的?hashCode方法返回的值是相同的。但是我們應該知道對于不同對象產生不同的哈希值對于哈希表(HashMap等等)能夠提高性能。

equals方法和hashCode方法會在哪用到

這兩個方法經常出現在Java中的哪個類里面呢?如果看過?HashMap源碼的應該了解這兩個方法經常出現在?HashMap中。網上介紹?HashMap類的文章有很多了,這里就簡單介紹一下?HashMap

當一個節點中的鏈表超過了8的時候就會變為紅黑樹,以解決鏈表長度過長以后查詢速度慢的缺點。

57e4285c3456cdd330db06930d772abe.png

HashMap是由數組和鏈表組成的高效存儲數據的結構。那么是如何確定一個數據存儲在數組中的哪個位置呢?就是通過?hashCode方法進行計算出存儲在哪個位置,還記得我們上面講?hashCode方法說了有可能兩個不同對象的?hashCode方法返回的值相同,那么此時就會產生沖突,產生沖突的話就會調用?equals方法進行比對,如果不同,那么就將其加入鏈表尾部,如果相同就替換原數據。

計算位置當然不是上面簡單的一個?hashCode方法就計算出來,中間還有一些其他的步驟,這里可以簡單的認為是?hashCode確定了位置。

什么時候去覆蓋這兩個方法呢?

如果你不將自定義的類定義為?HashMap的key值的話,那么我們重寫了?equals方法而沒有重寫?hashCode方法,編譯器不會報任何錯,在運行時也不會拋任何異常。

如果你想將自定義的類定義為?HashMap的key值得話,那么如果重寫了?equals?方法那么就必須也重寫?hashCode方法。

接下來我們可以看一下我們使用自定義的類作為?HashMap的key,并且自定義的類不重寫?equals和?hashCode方法會發生什么。

自定義的類

@Builder

@NoArgsConstructor

@AllArgsConstructor

class CustomizedKey{

private Integer id;

private String name;

}

接下來我們看使用自定義的類作為key

public static void main(String[] args) {

Map<CustomizedKey, Integer> data = getData();

CustomizedKey key = CustomizedKey.builder().id(1).name("key").build();

Integer integer = data.get(key);

System.out.printf(String.valueOf(integer));

}

private static Map<CustomizedKey,Integer> getData(){

Map<CustomizedKey,Integer> customizedKeyIntegerMap = new HashMap<>();

CustomizedKey key = CustomizedKey.builder().id(1).name("key").build();

customizedKeyIntegerMap.put(key,10);

return customizedKeyIntegerMap;

}

我們可以看到程序最后打印的是一個?null值。原因正如上面我們說的一樣。

  • hashCode:用來計算該對象放入數組中的哪個位置,因為是兩個都是new的對象,所以即使里面的值一樣,但是對象所處的地址卻不同,所以使用默認的?hashCode也就不同,當然在?hashMap中就不會認為兩個是一個對象。

接下來我們就重寫一下這兩個方法。如果我們使用?IDEA的話,那么直接使用快捷鍵即可。

0226ded8d7e7b0b13ea514bdd9837ca8.png

接下來我們看我們實現的兩個方法

@Builder

@NoArgsConstructor

@AllArgsConstructor

class CustomizedKey{

private Integer id;

private String name;

@Override

public boolean equals(Object o) {

if (this == o) return true;

if (o == null || getClass() != o.getClass()) return false;

CustomizedKey that = (CustomizedKey) o;

return Objects.equals(id, that.id) &&

Objects.equals(name, that.name);

}

@Override

public int hashCode() {

return Objects.hash(id, name);

}

}

然后我們再次運行上面的程序發現輸出打印已經變成了?10

我們也能夠使用?Lombock提供的?@EqualsAndHashCode注解簡化代碼

代碼地址:https://github.com/modouxiansheng/Doraemon


(完)

MarkerHub文章索引:

https://github.com/MarkerHub/JavaIndex

【推薦閱讀】

知乎問答:搞開發就怕加班還學不到東西?

很全很牛逼,看完這篇Elasticsearch實戰,我覺得我可以寫個百度~

基于Jwt資源無狀態認證權限管理系統bootshiro

別用Date了,Java8新特性之日期處理,現在學會也不遲!

eblog項目講解視頻上線啦,長達17個小時!!

e8211e91bfd3eebc5cc142d90f5d44b6.png

好文章!點個在看!

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

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

相關文章

ssh客戶端_一款基于TAS框架的SSH客戶端蠕蟲

TEA是一款基于TAS框架的SSH客戶端蠕蟲&#xff0c;從本質上說&#xff0c;它是一個仿冒的SSH客戶端&#xff0c;它能夠修改tty輸入/輸出來實現任意命令執行&#xff0c;或通過SSH連接來上傳自身以實現滲透感染。為了實現該工具的正常功能&#xff0c;遠程主機需要滿足以下條件&…

Selenium入門11 滾動條控制(通過js)

這一節要有js基礎。做web端的UI自動化必須要有html&#xff0c;css&#xff0c;javascript前端基礎。 滾動條控制&#xff1a; 1 移動垂直滾動條 document.documentElement.scrollTop 2 移動垂直滾動條 document.documentElement.scrollLeft 3 找到某個元素&#xff0c;移動到可…

Qt之QNetworkInterface

簡述 QNetworkInterface類負責提供主機的IP地址和網絡接口的列表。 QNetworkInterface表示了當前程序正在運行時與主機綁定的一個網絡接口。每個網絡接口可能包含0個或多個IP地址&#xff0c;每個IP地址都可選擇性地與一個子網掩碼和/或一個廣播地址相關聯。這樣的列表可以通過…

第二周計劃

上周計劃回顧 3.5 ~ 3.11 數據&#xff1a; 評師網爬取&#xff0c;完成&#xff1a;2k條記錄 finished后端 數據結構 技術選型 學校API封裝未完成&#xff1a;后端負責人出差 工作暫停產品 功能設計&#xff1a;主要功能提交&#xff1a;原型圖 幾個頁面 每個頁面大概功能完成…

python編程軟件排行榜_PYPL 9月編程語言排行榜發布 Python一枝獨秀

開發者可以將 PYPL 作為一個參考&#xff0c;決定學習何種語言或 IDE&#xff0c;或者在新的軟件項目中使用何種語言或數據庫。9 月份的榜單如下&#xff1a;前五名分別是 Python、Java、JavaScript、C# 與 PHP。相比去年 9 月份的數據&#xff0c;除了 Python 大幅上漲了 4.5%…

分享到系統面板_win7電腦沒有nvidia控制面板怎么辦【解決方法】

我們在使用電腦的時候&#xff0c;當電腦顯卡出現問題導致屏幕畫面不清晰時&#xff0c;可以使用win7系統自帶nvidia控制面板&#xff0c;它能夠對顯卡進行設置&#xff0c;提升顯卡功能&#xff0c;不過很多電腦用戶點擊nvidia控制面板時卻提示nvidia顯示設置不可用&#xff0…

Python之數據加密與解密(hashlib、hmac、random、base64、pycrypto)--轉載

本文內容 數據加密概述Python中實現數據加密的模塊簡介hashlib與hmac模塊介紹random與secrets模塊介紹base64模塊介紹pycrypto模塊介紹總結參考文檔提示&#xff1a; Python 2.7中的str是字節串&#xff0c;而Python 3.x中的str是字符串。本文中的代碼都是通過Python 2.7實現的…

day3-文件操作之基本操作

一、文件的基本操作 文件內容&#xff1a; Somehow, it seems the love I knew was always the most destructive kind 不知為何&#xff0c;我經歷的愛情總是最具毀滅性的的那種 Yesterday when I was young 昨日當我年少輕狂1、read() 當read()函數中傳入整數(int)參數&#…

QT連接多種數據庫f方法及測試

QT提供了對多種數據庫的訪問支持&#xff0c;對SQL Server也可以通過ODBC來進行訪問。要想順利訪問SQL Server。 首先要保證以下幾點&#xff1a;1. QT編譯時已經編譯了QtSql2. 編譯了ODBC插件。可以通過 configure -plugin-sql-odbc來保證&#xff0c;也可以單獨編譯~/src/plu…

服務器如何實現電腦無線橋接,無線路由器WDS橋接成功副路由器下電腦無法上網怎么辦【解決方法】...

摘 要無線WDS橋接設置完成后&#xff0c;在副路由器管理面&#xff0c;運行狀態 無線狀態 中&#xff0c;WDS狀態顯示成功&#xff0c;但電腦通過副路由無法上網。該問題可能與主、副路由器的設置有關&#xff0c;如下圖所示&#xff1a; 解決辦法&#xff1a; 排查一&#xff…

spad 探測器_從光到光子—“單光子”探測器

光電探測器光電探測器是指在光輻射作用下將其非傳導電荷變為傳導電荷的一類器件。在電子學中&#xff0c;二極管是一種具有不對稱傳輸特性的雙端電子元件&#xff0c;在一個方向上對電流具有低(理想為零)電阻&#xff0c;在另一個方向上具有高(理想為無限)電阻。最常見的類型如…

天地圖專題五:在天地圖上繪制電子區域并保存數據

版權聲明&#xff1a;本文為博主原創文章&#xff0c;轉載請注明出處。 上一文章講了如何在天地圖上顯示坐標軌跡。 本文介紹如何在天地圖上繪制電子區域&#xff08;電子范圍或電子柵欄&#xff09;&#xff0c;并且&#xff0c;我們要將我們繪制的電子區域的坐標數據保存到數…

Mysql中natural join和inner join的區別

假設有如下兩個表TableA&#xff0c;TableB TableA TableB Column1 Column2 Column1 Column3 1 2 1 3TableA的Column1列名和TableB的Column1列名相同。 SELECT * FROM TableA INNER JOIN TableB USING (Column1) SEL…

微信和支付寶的服務器在哪里,手機恢復出廠設置,里面支付寶與微信怎么辦?原來數據在這里...

當手機使用一段時間之后&#xff0c;因為硬件落后會出現卡頓、內存不足等情況&#xff0c;這個時候提高手機速度最直接的一個辦法就是恢復出廠設置&#xff0c;雖然不能從根源上解決問題&#xff0c;但是還是可以湊合個半年時間的。那么這個時候就出現一個問題&#xff0c;手機…

python線上編輯問題_python django - static文件處理與線上部署測試

static文件相關操作涉及&#xff1a;a. 文件位置與訪問路徑映射b. setting.py與static相關配置STATIC_URLSTATIC_ROOTSTATICFILES_DIRSc. html中對于static文件引用方式d. python manage.py collectstatic1. 開發環境-目錄結構2. setting.py 設置STATIC_URL /static/# STATIC_…

android arcgis 繪制圓_arcgis for android 定位 圓

不多說直接代碼 &#xff0c;群里人共享的方法一&#xff1a; /*** 繪制圓,配合 cleargraphicLayer()清除** param center 圓心* param radius 半徑* param alpha 填充的透明度 0-100* param fillColor 填充的顏色*/public void DrawCircle(Point center, double radius, int a…

CreateSolidBrush

[聲明] WINGDIAPI HBRUSH WINAPI CreateSolidBrush(COLORREF color); [功能] 初始化一個指定顏色的畫刷。畫筆可以隨后被選為任何設備上下文的當前刷子。 [參數表] color 畫刷的顏色[返回值] Long&#xff0c;如函數執行成功&#xff0c;就返回指向新畫筆的一個句柄&#xff1b…

mysql insert 不需要日志_MySQL數據庫性能優化(1)「轉」

1、MySQL概述從本文開始我們將討論建立在塊存儲方案之上的關系型數據庫的性能優化方案和集群方案。關系型數據庫的選型將以創業公司、互聯網行業使用最廣泛的MySQL數據為目標&#xff0c;但是MySQL的安裝過程和基本使用方法等知識并不在我們討論的范圍內。后續幾篇文章我們首先…

javascript面試題以及對所涉及到的知識點的總結

前言 這幾天將js方面的知識系統的回顧了一遍&#xff0c;但是當嘗試去做一些面試題時覺得解決問題的能力以及效率還是有所欠缺&#xff0c;在這里特意記錄一下所做的面試題并總結所涉及到的相關知識點。 一、面試題、答案以及總結 1、截取字符串abcdefg的efg var str"abcd…

十代主板改win7_技嘉B460主板UEFI+GPT裝win7|10代CPU裝win7 Bios設置

隨著英特爾十代酷睿處理器的全面上市,針對主流用戶的B460平臺成為了大眾主要關注的目標。作為國際一線板卡品牌的技嘉科技針對十代酷睿的特點,推出了B460主板。這塊主板裝win7、win10都可以,但是在裝win7的過程中USB設備不能使用(本站支持最新的B460/Z490等新主板驅動),需要…