亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

java中hashCode、equals的使用方法教程

2024-07-13 10:15:30
字體:
來源:轉載
供稿:網友

前言

眾所周知Java.lang.Object 有一個hashCode()和一個equals()方法,這兩個方法在軟件設計中扮演著舉足輕重的角色。在一些類中重寫這兩個方法以完成某些重要功能。

1、為什么要用 hashCode()?

集合Set中的元素是無序且不可重復的,那判斷兩個元素是否重復的依據是什么呢?

有人說:比較對象是否相等當然用Object.equal()了。但是,Set中存在大量對象,后添加到集合Set中的對象元素比較次數會逐漸增多,大大降低了程序運行效率。 Java中采用哈希算法(也叫散列算法)來解決這個問題,將對象(或數據)依特定算法直接映射到一個地址上,對象的存取效率大大提高。

這樣一來,當含有海量元素的集合Set需要添加某元素(對象)時,先調用這個元素的hashCode(),就能一下子定位到此元素實際存儲位置,如果這個位置沒有元素,說明此對象是第一次存儲到集合Set, 直接將此對象存儲在此位置上;若此位置有對象存在,調用equal()看看這兩個對象是否相等,相等就舍棄此元素不存,不等則散列到其他地址。

這也是為什么set集合存儲對象類型數據的時候,要不僅僅重寫對象的hashCode()方法還要重寫equals()方法的原因。

2、HOW use hashCode()?

hashCode()的返回值和equals()的關系

  • 如果a.equals(b)返回“true”,那么a和b的hashCode()一定相等。
  • 如果a.equals(b)返回“false”,那么a和b的hashCode()有可能相等,也有可能不等。

下面是一個例子。在實際的軟件開發中,最好重寫這兩個方法。

public class Employee { int  employeeId; String  name; @Override public boolean equals(Object obj) {  if(obj==this)   return true;  Employee emp=(Employee)obj;  if(employeeId.equals(emp.getEmployeeId()) && name==emp.getName())   return true;  return false; } @Override public int hashCode() {  int hash = 1;  hash = hash * 17 + employeeId;  hash = hash * 31 + name.hashCode();  return hash; }}

equals()和hashCode()方法是用來在同一類中做比較用的,尤其是在容器里如set存放同一類對象時用來判斷放入的對象是否重復。

這里我們首先要明白一個問題:

equals()相等的兩個對象,hashcode()一定相等,equals()不相等的兩個對象,卻并不能證明他們的hashcode()不相等。換句話說,equals()方法不相等的兩個對象,hashCode()有可能相等。

在這里hashCode就好比字典里每個字的索引,equals()好比比較的是字典里同一個字下的不同詞語。就好像在字典里查“自”這個字下的兩個詞語“自己”、“自發”,如果用equals()判斷查詢的詞語相等那么就是同一個詞語,比如equals()比較的兩個詞語都是“自己”,那么此時hashCode()方法得到的值也肯定相等;如果用equals()方法比較的是“自己”和“自發”這兩個詞語,那么得到結果是不想等,但是這兩個詞都屬于“自”這個字下的詞語所以在查索引時相同,即:hashCode()相同。如果用equals()比較的是“自己”和“他們”這兩個詞語的話那么得到的結果也是不同的,此時hashCode() 得到也是不同的。

反過來:hashcode()不等,一定能推出equals()也不等;hashcode()相等,equals()可能相等,也可能不等。

在object類中,hashcode()方法是本地方法,返回的是對象的地址值,而object類中的equals()方法比較的也是兩個對象的地址值,如果equals()相等,說明兩個對象地址值也相等,當然hashcode() 也就相等了。

既然equals比較元素相等更準確,那么為什么還要用hashCode( )方法呢?

因為hash算法對于查找元素提供了很高的效率,如果想查找一個集合中是否包含有某個對象,大概的程序代碼怎樣寫呢?
你通常是逐一取出每個元素與要查找的對象進行比較,當發現某個元素與要查找的對象進行equals方法比較的結果相等時,則停止繼續查找并返回肯定的信息,否則,返回否定的信息,如果一個集合中有很多個元素,比如有一萬個元素,并且沒有包含要查找的對象時,則意味著你的程序需要從集合中取出一萬個元素進行逐一比較才能得到結論。

Object類中定義了一個hashCode()方法來返回每個Java對象的哈希碼,當從HashSet集合中查找某個對象時,Java系統首先調用對象的hashCode()方法獲得該對象的哈希碼表,然后根據哈希嗎找到相應的存儲區域,最后取得該存儲區域內的每個元素與該對象進行equals方法比較;這樣就不用遍歷集合中的所有元素就可以得到結論,可見,HashSet集合具有很好的對象檢索性能。

但是,HashSet集合存儲對象的效率相對要低些,因為向HashSet集合中添加一個對象時,要先計算出對象的哈希碼和根據這個哈希碼確定對象在集合中的存放位置為了保證一個類的實例對象能在HashSet正常存儲,要求這個類的兩個實例對象用equals()方法比較的結果相等時,他們的哈希碼也必須相等;也就是說,如果obj1.equals(obj2)的結果為true,那么以下表達式的結果也要為true:obj1.hashCode() == obj2.hashCode() 。

換句話說:當我們重寫一個對象的equals方法,就必須重寫他的hashCode方法,不重寫他的hashCode方法的話,Object對象中的hashCode方法始終返回的是一個對象的hash地址,而這個地址是永遠不相等的。所以這時候即使是重寫了equals方法,也不會有特定的效果的,因為hashCode方法如果都不想等的話,就不會調用equals方法進行比較了,所以沒有意義了。

大多數的數據結構通過equals方法來判斷他們是否包含一個元素,例如:

List<String> list = Arrays.asList("a", "b", "c");boolean contains = list.contains("b");

這個變量contains結果是true,因為,雖然”b”是不相同的實例(此外,忽略字符串駐留),但是他們是相等的。

他們通過使用一種快捷的方式(減少潛在的實例相等)進行比較,從而代替通過比較實例所包含的每個元素。而快捷比較僅需要比較下面這些方面:

快捷方式比較即通過比較哈希值,它可以將一個實例用一個整數值來代替。哈希碼相同的實例不一定相等,但相等的實例一定具有有相同的哈希值。(或應該有,我們很快就會討論這個)這些數據結構經常通過這種這種技術來命名,可以通過Hash來識別他們的,其中,HashMap是其中最著名的代表。

它們通常是這樣這樣運作的:

當添加一個元素,它的哈希碼是用來計算內部數組的索引(即所謂的桶)

如果是,不相等的元素有相同的哈希碼,他們最終在同一個桶上并且捆綁在一起,例如通過添加到列表。
當一個實例來進行contains操作時,它的哈希碼將用來計算桶值(索引值),只有當對應索引值上存在元素時,才會對實例進行比較。

因此equals,hashCode是定義在Object類中。

如果hashCode作為快捷方式來確定相等,那么只有一件事我們應該關心:相等的對象應該具有相同的哈希碼,這也是為什么如果我們重寫了equals方法后,我們必須創建一個與之匹配的hashCode實現的原因!

否則相等的對象是可能不會有相同的哈希碼的,因為它們將調用的是Object's的默認實現。

引用自官方文檔

hashCode通用約定:

調用運行Java應用程序中的同一對象,hashCode方法必須始終返回相同的整數。這個整數不需要在不同的Java應用程序中保持一致。根據equals(Object)的方法來比較,如果兩個對象是相等的,兩個對象調用hashCode方法必須產生相同的結果。

根據equals(Object)的方法是比較,如果兩個對象是不相等的,那么兩個對象調用hashCode方法并不一定產生不同的整數的結果。但是,程序員應該意識到給不相等的對象產生不同的整數結果將有可能提高哈希表的性能。

HashCode實現

下面是簡單的person.hashcode()的實現:

@Overridepublic int hashCode() { return Objects.hash(firstName, lastName);}

person's是通過多個字段結合來計算哈希碼的。都是通過Object的hash函數來計算。

選擇字段

但哪些字段是相關的呢?需求將會幫助我們回答這個問題:

如果相等的對象必須具有相同的哈希碼,那么計算哈希碼就不應包括任何不用于相等檢查的字段。(否則兩個對象只是這些字段不同但是仍然有可能會相等,此時他們這兩個對象哈希碼卻會不相同。)所以用于哈希組字段應該相等時使用的字段的子集。默認情況下都使用相同的字段,但有一些細節需要考慮。

總結

我們了解到計算哈希碼就是壓縮相等的一個整數值:相等的對象必須有相同的哈希碼,而出于對性能的考慮:最好是盡可能少的不相等的對象共享相同的哈希碼。

這就意味著如果重寫了equals方法,那么就必須重寫hashCode方法

當實現hashCode使用與equals中使用的相同的字段(或者equals中使用字段的子集)

最好不要包含可變的字段。對集合不要考慮調用hashCode,如果沒有特殊的輸入特定的模式,盡量采用通用的哈希算法

好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VeVb武林網的支持。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲国产成人在线播放| 欧美性生交xxxxxdddd| 欧美高清在线观看| 91丨九色丨国产在线| 亚洲成在人线av| 中文字幕在线国产精品| 欧美精品做受xxx性少妇| 久久久久久久久久久人体| 日韩视频免费中文字幕| 日韩一区二区三区国产| 欧美日韩第一视频| 国产午夜精品视频免费不卡69堂| 亚洲欧美色婷婷| 久久精品国产96久久久香蕉| 97视频网站入口| 国模gogo一区二区大胆私拍| 久久久精品视频在线观看| 亚洲精品久久视频| 亚洲国产一区自拍| 亚洲电影免费观看高清完整版在线观看| 91在线免费网站| 午夜精品99久久免费| 国产做受高潮69| 欧美激情第1页| 国产精品久久久久999| 亚洲人成啪啪网站| 国产美女精品视频免费观看| 亚洲www在线| 亚洲国产91精品在线观看| 91亚洲精品在线观看| 国产精品白嫩美女在线观看| 庆余年2免费日韩剧观看大牛| 日韩av在线网址| 欧美大胆a视频| 欧美性高潮床叫视频| 国产婷婷色综合av蜜臀av| 欧美国产第一页| 中文字幕日韩精品有码视频| 欧美大荫蒂xxx| 亚洲free性xxxx护士hd| 国产精品看片资源| 午夜美女久久久久爽久久| 国产精品成人av在线| 在线观看91久久久久久| 91精品免费视频| 日韩在线观看免费网站| 国产成人精品国内自产拍免费看| 国产日韩欧美在线观看| 午夜精品久久久久久99热| 日韩av手机在线观看| 久久久久久久久久亚洲| 在线日韩第一页| 亚洲一区av在线播放| 久久成人免费视频| 国产91在线高潮白浆在线观看| 色综久久综合桃花网| 亚洲欧美综合v| 欧美大尺度电影在线观看| 97视频在线播放| 精品久久久久国产| 亚洲色图欧美制服丝袜另类第一页| 亚洲一区二区三区视频播放| 最新亚洲国产精品| 久久亚洲综合国产精品99麻豆精品福利| 91香蕉嫩草神马影院在线观看| 亚洲石原莉奈一区二区在线观看| 亚洲第一精品久久忘忧草社区| 欧美性xxxxx极品娇小| 亚洲第一福利在线观看| 91精品视频在线免费观看| 日韩二区三区在线| 久久香蕉频线观| 久久精品中文字幕电影| 亚洲国产另类 国产精品国产免费| 亚洲激情国产精品| 欧美丝袜美女中出在线| 亚洲国产精品字幕| 91精品久久久久久久久不口人| 日韩av日韩在线观看| 国产精品一久久香蕉国产线看观看| 欧美人与物videos| 国产成人啪精品视频免费网| 久久久久国产一区二区三区| 不卡在线观看电视剧完整版| 日本视频久久久| 日韩成人在线电影网| 日本亚洲欧美三级| 91久久久亚洲精品| 国产精品精品视频一区二区三区| 欧美在线免费看| 九九久久久久久久久激情| 国产精品高清网站| 国产精品专区一| 国产精品免费观看在线| 亚洲视频网站在线观看| 欧美一性一乱一交一视频| 91精品久久久久久久久久久久久| 中文字幕视频在线免费欧美日韩综合在线看| 亚洲欧美日韩精品| 欧美性猛交99久久久久99按摩| 欧美区在线播放| 91精品视频播放| 欧美精品18videos性欧| 久久人91精品久久久久久不卡| 欧美一区二区三区四区在线| 精品日韩中文字幕| 中文字幕欧美日韩在线| 久久久久国产精品免费网站| 欧美成人精品激情在线观看| 色悠久久久久综合先锋影音下载| 欧美二区在线播放| 欧美俄罗斯性视频| 欧美一级视频一区二区| 亚洲国产欧美一区二区丝袜黑人| 日本aⅴ大伊香蕉精品视频| 91精品国产777在线观看| 日韩视频免费大全中文字幕| 奇门遁甲1982国语版免费观看高清| 一个色综合导航| 欧美怡红院视频一区二区三区| 久久香蕉国产线看观看av| 九九热r在线视频精品| 国产日韩综合一区二区性色av| 久久视频在线视频| 一区二区三区视频在线| 欧美怡春院一区二区三区| 亚洲高清久久网| 亚洲精品视频免费在线观看| 操91在线视频| 亚洲国产精品一区二区三区| 国精产品一区一区三区有限在线| 国内外成人免费激情在线视频网站| 国产xxx69麻豆国语对白| 欧美成人免费播放| 日本免费在线精品| 亚洲欧美日韩精品久久奇米色影视| 91久久久久久久久久久| 亚洲欧美中文另类| 欧美激情在线狂野欧美精品| 97免费视频在线| 91av视频在线免费观看| 美女久久久久久久| 亚洲视频在线观看网站| 中文字幕亚洲欧美一区二区三区| 国产精品亚洲一区二区三区| 国产精品欧美激情在线播放| 色偷偷偷亚洲综合网另类| 久久免费视频在线| 欧美激情一区二区久久久| 亚洲国产欧美在线成人app| 最新的欧美黄色| 日韩中文字幕精品视频| 91人人爽人人爽人人精88v| 日韩av不卡电影| 亚洲欧美日韩久久久久久| 国产精品第七十二页| 国产91精品久| 日本午夜精品理论片a级appf发布| 久久琪琪电影院| 69av在线播放| 久久夜色精品国产欧美乱| 中文字幕av一区二区三区谷原希美| 成人黄色在线播放| 91av在线国产|