最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java中hashCode方法與equals方法的用法總結(jié)

 更新時間:2013年10月22日 09:14:44   作者:  
總的來說,Java中的集合(Collection)有兩類,一類是List,再有一類是Set。前者集合內(nèi)的元素是有序的,元素可以重復(fù);后者元素?zé)o序,但元素不可重復(fù)

首先,想要明白hashCode的作用,必須要先知道Java中的集合。  

總的來說,Java中的集合(Collection)有兩類,一類是List,再有一類是Set。 前者集合內(nèi)的元素是有序的,元素可以重復(fù);后者元素?zé)o序,但元素不可重復(fù)。

那么這里就有一個比較嚴重的問題了:要想保證元素不重復(fù),可兩個元素是否重復(fù)應(yīng)該依據(jù)什么來判斷呢? 這就是Object.equals方法了。但是,如果每增加一個元素就檢查一次,那么當(dāng)元素很多時,后添加到集合中的元素比較的次數(shù)就非常多了。 也就是說,如果集合中現(xiàn)在已經(jīng)有1000個元素,那么第1001個元素加入集合時,它就要調(diào)用1000次equals方法。這顯然會大大降低效率。  

于是,Java采用了哈希表的原理。哈希(Hash)實際上是個人名,由于他提出一哈希算法的概念,所以就以他的名字命名了。 哈希算法也稱為散列算法,是將數(shù)據(jù)依特定算法直接指定到一個地址上。初學(xué)者可以這樣理解,hashCode方法實際上返回的就是對象存儲的物理地址(實際可能并不是)。  

這樣一來,當(dāng)集合要添加新的元素時,先調(diào)用這個元素的hashCode方法,就一下子能定位到它應(yīng)該放置的物理位置上。 如果這個位置上沒有元素,它就可以直接存儲在這個位置上,不用再進行任何比較了;如果這個位置上已經(jīng)有元素了, 就調(diào)用它的equals方法與新元素進行比較,相同的話就不存了,不相同就散列其它的地址。 所以這里存在一個沖突解決的問題。這樣一來實際調(diào)用equals方法的次數(shù)就大大降低了,幾乎只需要一兩次。 

所以,Java對于eqauls方法和hashCode方法是這樣規(guī)定的:

1、如果兩個對象相同,那么它們的hashCode值一定要相同;

2、如果兩個對象的hashCode相同,它們并不一定相同(上面說的對象相同指的是用eqauls方法比較。)  

你當(dāng)然可以不按要求去做了,但你會發(fā)現(xiàn),相同的對象可以出現(xiàn)在Set集合中。同時,增加新元素的效率會大大下降。

hashcode這個方法是用來鑒定2個對象是否相等的。 那你會說,不是還有equals這個方法嗎? 不錯,這2個方法都是用來判斷2個對象是否相等的。但是他們是有區(qū)別的。 一般來講,equals這個方法是給用戶調(diào)用的,如果你想判斷2個對象是否相等,你可以重寫equals方法,然后在代碼中調(diào)用,就可以判斷他們是否相等 了。簡單來講,equals方法主要是用來判斷從表面上看或者從內(nèi)容上看,2個對象是不是相等。

舉個例子,有個學(xué)生類,屬性只有姓名和性別,那么我們可以 認為只要姓名和性別相等,那么就說這2個對象是相等的。 hashcode方法一般用戶不會去調(diào)用,比如在hashmap中,由于key是不可以重復(fù)的,他在判斷key是不是重復(fù)的時候就判斷了hashcode 這個方法,而且也用到了equals方法。這里不可以重復(fù)是說equals和hashcode只要有一個不等就可以了!所以簡單來講,hashcode相 當(dāng)于是一個對象的編碼,就好像文件中的md5,他和equals不同就在于他返回的是int型的,比較起來不直觀。我們一般在覆蓋equals的同時也要 覆蓋hashcode,讓他們的邏輯一致。舉個例子,還是剛剛的例子,如果姓名和性別相等就算2個對象相等的話,那么hashcode的方法也要返回姓名 的hashcode值加上性別的hashcode值,這樣從邏輯上,他們就一致了。 要從物理上判斷2個對象是否相等,用==就可以了。

在Java語言中,equals()和hashCode()兩個函數(shù)的使用是緊密配合的,你要是自己設(shè)計其中一個,就要設(shè)計另外一個。在多數(shù)情況 下,這兩個函數(shù)是不用考慮的,直接使用它們的默認設(shè)計就可以了。但是在一些情況下,這兩個函數(shù)最好是自己設(shè)計,才能確保整個程序的正常運行。最常見的是當(dāng) 一個對象被加入收集對象(collection object)時,這兩個函數(shù)必須自己設(shè)計。更細化的定義是:如果你想將一個對象A放入另一個收集對象B里,或者使用這個對象A為查找一個元對象在收集對 象B里位置的鑰匙,并支持是否容納,刪除收集對象B里的元對象這樣的操作,那么,equals()和hashCode()函數(shù)必須開發(fā)者自己定義。其他情 況下,這兩個函數(shù)是不需要定義的。

equals():

它是用于進行兩個對象的比較的,是對象內(nèi)容的比較,當(dāng)然也能用于進行對象參閱值的比較。什么是對象參閱值的比較?就是兩個參閱變量的值得比較,我們 都知道參閱變量的值其實就是一個數(shù)字,這個數(shù)字可以看成是鑒別不同對象的代號。兩個對象參閱值的比較,就是兩個數(shù)字的比較,兩個代號的比較。這種比較是默 認的對象比較方式,在Object這個對象中,這種方式就已經(jīng)設(shè)計好了。所以你也不用自己來重寫,浪費不必要的時間。

對象內(nèi)容的比較才是設(shè)計equals()的真正目的,Java語言對equals()的要求如下,這些要求是必須遵循的。否則,你就不該浪費時間:

•對稱性:如果x.equals(y)返回是“true”,那么y.equals(x)也應(yīng)該返回是“true”。

•反射性:x.equals(x)必須返回是“true”。

•類推性:如果x.equals(y)返回是“true”,而且y.equals(z)返回是“true”,那么z.equals(x)也應(yīng)該返回是“true”。

•還有一致性:如果x.equals(y)返回是“true”,只要x和y內(nèi)容一直不變,不管你重復(fù)x.equals(y)多少次,返回都是“true”。

•任何情況下,x.equals(null),永遠返回是“false”;x.equals(和x不同類型的對象)永遠返回是“false”。

hashCode():
這個函數(shù)返回的就是一個用來進行赫希操作的整型代號,請不要把這個代號和前面所說的參閱變量所代表的代號弄混了。后者不僅僅是個代號還具有在內(nèi)存中才查找對 象的位置的功能。hashCode()所返回的值是用來分類對象在一些特定的收集對象中的位置。這些對象是HashMap, Hashtable, HashSet,等等。這個函數(shù)和上面的equals()函數(shù)必須自己設(shè)計,用來協(xié)助HashMap, Hashtable, HashSet,等等對自己所收集的大量對象進行搜尋和定位。

這些收集對象究竟如何工作的,想象每個元對象hashCode是一個箱子的 編碼,按照編碼,每個元對象就是根據(jù)hashCode()提供的代號歸入相應(yīng)的箱子里。所有的箱子加起來就是一個HashSet,HashMap,或 Hashtable對象,我們需要尋找一個元對象時,先看它的代碼,就是hashCode()返回的整型值,這樣我們找到它所在的箱子,然后在箱子里,每 個元對象都拿出來一個個和我們要找的對象進行對比,如果兩個對象的內(nèi)容相等,我們的搜尋也就結(jié)束。這種操作需要兩個重要的信息,一是對象的 hashCode(),還有一個是對象內(nèi)容對比的結(jié)果。

hashCode()的返回值和equals()的關(guān)系如下:

•如果x.equals(y)返回“true”,那么x和y的hashCode()必須相等。

•如果x.equals(y)返回“false”,那么x和y的hashCode()有可能相等,也有可能不等。

為什么這兩個規(guī)則是這樣的,原因其實很簡單,拿HashSet來說吧,HashSet可以擁有一個或更多的箱子,在同一個箱子中可以有一個 或更多的獨特元對象(HashSet所容納的必須是獨特的元對象)。這個例子說明一個元對象可以和其他不同的元對象擁有相同的hashCode。但是一個 元對象只能和擁有同樣內(nèi)容的元對象相等。所以這兩個規(guī)則必須成立。

設(shè)計這兩個函數(shù)所要注意到的:
如果你設(shè)計的對象類型并不使用于收集性對象,那么沒有必要自己再設(shè)計這兩個函數(shù)的處理方式。這是正確的面向?qū)ο笤O(shè)計方法,任何用戶一時用不到的功能,就先不要設(shè)計,以免給日后功能擴展帶來麻煩。

如果你在設(shè)計時想別出心裁,不遵守以上的兩套規(guī)則,那么勸你還是不要做這樣想入非非的事。我還沒有遇到過哪一個開發(fā)者和我說設(shè)計這兩個函數(shù)要違背前面說的兩個規(guī)則,我碰到這些違反規(guī)則的情況時,都是作為設(shè)計錯誤處理。

當(dāng)一個對象類型作為收集型對象的元對象時,這個對象應(yīng)該擁有自己處理equals(),和/或處理hashCode()的設(shè)計,而且要遵守前面所說 的兩種原則。equals()先要查null和是否是同一類型。查同一類型是為了避免出現(xiàn)ClassCastException這樣的異常給丟出來。查 null是為了避免出現(xiàn)NullPointerException這樣的異常給丟出來。

如果你的對象里面容納的數(shù)據(jù)過多,那么這兩個函數(shù) equals()和hashCode()將會變得效率低。如果對象中擁有無法serialized的數(shù)據(jù),equals()有可能在操作中出現(xiàn)錯誤。想象 一個對象x,它的一個整型數(shù)據(jù)是transient型(不能被serialize成二進制數(shù)據(jù)流)。然而equals()和hashCode()都有依靠 這個整型數(shù)據(jù),那么,這個對象在serialization之前和之后,是否一樣?答案是不一樣。因為serialization之前的整型數(shù)據(jù)是有效的 數(shù)據(jù),在serialization之后,這個整型數(shù)據(jù)的值并沒有存儲下來,再重新由二進制數(shù)據(jù)流轉(zhuǎn)換成對象后,兩者(對象在serialization 之前和之后)的狀態(tài)已經(jīng)不同了。這也是要注意的。

知道以上這些能夠幫助你:

1. 進行更好的設(shè)計和開發(fā)。

2. 進行更好的測試案例開發(fā)。

3. 在面試過程中讓面試者對你的學(xué)識淵博感到滿意。

相關(guān)文章

  • 使用hutool進行ftp文件下載和上傳詳細代碼示例

    使用hutool進行ftp文件下載和上傳詳細代碼示例

    在開發(fā)Java項目時,FTP客戶端是經(jīng)常需要使用的工具,因為FTP協(xié)議在文件傳輸方面有著廣泛的應(yīng)用,這篇文章主要給大家介紹了關(guān)于使用hutool進行ftp文件下載和上傳的相關(guān)資料,需要的朋友可以參考下
    2024-02-02
  • Spring自定義注解實現(xiàn)數(shù)據(jù)脫敏

    Spring自定義注解實現(xiàn)數(shù)據(jù)脫敏

    在當(dāng)今數(shù)據(jù)安全越來越受到重視的背景下,許多企業(yè)都對敏感數(shù)據(jù)的保護有著嚴格的要求,本文就來深入探討一下如何自定義注解來實現(xiàn)對敏感數(shù)據(jù)的脫敏處理吧
    2024-11-11
  • Java?Swing實現(xiàn)畫板的簡單操作

    Java?Swing實現(xiàn)畫板的簡單操作

    這篇文章主要介紹了Java?Swing實現(xiàn)畫板的簡單操作,修改顏色,更改圖形,清除,任務(wù)欄按鈕,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • Java基礎(chǔ)之static的用法

    Java基礎(chǔ)之static的用法

    這篇文章主要介紹了Java基礎(chǔ)之static的用法,文中有非常詳細的代碼示例,對正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有很大的幫助,需要的朋友可以參考下
    2021-05-05
  • 基于SpringBoot和PostGIS的某國基地可視化實戰(zhàn)

    基于SpringBoot和PostGIS的某國基地可視化實戰(zhàn)

    本文以Java開發(fā)語言為例,使用SpringBoot框架來進行后臺開發(fā),詳細講解如何使用Leaflet對PostGIS的全球基地信息進行Web可視化,最后分享Web可視化結(jié)果,感興趣的朋友跟隨小編一起看看吧
    2024-08-08
  • 解決Spring運行時報錯:Consider defining a bean of type ‘xxx.xxx.xxx.Xxx‘ in your configuration

    解決Spring運行時報錯:Consider defining a bean o

    該文章主要講述了在使用Spring框架時,如果遇到某個bean未找到的錯誤,應(yīng)該在配置文件中定義該bean,解決方法是在對應(yīng)的類上添加@Component注解
    2025-01-01
  • Springboot使用Maven占位符@替換不生效問題及解決

    Springboot使用Maven占位符@替換不生效問題及解決

    這篇文章主要介紹了Springboot使用Maven占位符@替換不生效問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Spring如何通過注解存儲和讀取對象詳解

    Spring如何通過注解存儲和讀取對象詳解

    在Spring中,要想更簡單的存儲和讀取對象的核心是使用注解,這篇文章主要給大家介紹了關(guān)于Spring如何通過注解存儲和讀取對象的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-07-07
  • java通過Excel批量上傳數(shù)據(jù)的實現(xiàn)示例

    java通過Excel批量上傳數(shù)據(jù)的實現(xiàn)示例

    Excel批量上傳是常見的一種功能,本文就來介紹一下java通過Excel批量上傳數(shù)據(jù)的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下
    2023-10-10
  • JAVA導(dǎo)出EXCEL表格的實例教學(xué)

    JAVA導(dǎo)出EXCEL表格的實例教學(xué)

    在本文中我們給大家整理了關(guān)于JAVA導(dǎo)出EXCEL表格的實例教學(xué)以及相關(guān)知識點,需要的朋友們學(xué)習(xí)下。
    2019-02-02

最新評論

清原| 崇文区| 盐津县| 云龙县| 五华县| 左贡县| 盐城市| 丘北县| 夏津县| 田林县| 雷州市| 云梦县| 神农架林区| 农安县| 海阳市| 三穗县| 历史| 麻栗坡县| 津南区| 准格尔旗| 七台河市| 岱山县| 怀仁县| 裕民县| 泸定县| 梁山县| 正蓝旗| 千阳县| 西华县| 怀安县| 色达县| 石棉县| 梓潼县| 迁安市| 和静县| 平阳县| 新民市| 随州市| 边坝县| 家居| 临湘市|