<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    大漠駝鈴

    置身浩瀚的沙漠,方向最為重要,希望此blog能向大漠駝鈴一樣,給我方向和指引。
    Java,Php,Shell,Python,服務器運維,大數據,SEO, 網站開發、運維,云服務技術支持,IM服務供應商, FreeSwitch搭建,技術支持等. 技術討論QQ群:428622099
    隨筆 - 238, 文章 - 3, 評論 - 117, 引用 - 0
    數據加載中……

    解析Java對象的equals()和hashCode()的使用

    原創 解析Java對象的equals()和hashCode()的使用 收藏

    解析Java對象的equals()和hashCode()的使用
    前言

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

    它是用于進行兩個對象的比較的,是對象內容的比較,當然也能用于進行對象參閱值的比較。什么是對象參閱值的比較?就是兩個參閱變量的值得比較,我們都知道 參閱變量的值其實就是一個數字,這個數字可以看成是鑒別不同對象的代號。兩個對象參閱值的比較,就是兩個數字的比較,兩個代號的比較。這種比較是默認的對 象比較方式,在Object這個對象中,這種方式就已經設計好了。所以你也不用自己來重寫,浪費不必要的時間。
    對象內容的比較才是設計equals()的真正目的,Java語言對equals()的要求如下,這些要求是必須遵循的。否則,你就不該浪費時間:

    * 對稱性:如果x.equals(y)返回是“true”,那么y.equals(x)也應該返回是“true”。
    * 反射性:x.equals(x)必須返回是“true”。
    * 類推性:如果x.equals(y)返回是“true”,而且y.equals(z)返回是“true”,那么z.equals(x)也應該返回是“true”。
    * 還有一致性:如果x.equals(y)返回是“true”,只要x和y內容一直不變,不管你重復x.equals(y)多少次,返回都是“true”。
    * 任何情況下,x.equals(null),永遠返回是“false”;x.equals(和x不同類型的對象)永遠返回是“false”。

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

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

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

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


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

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

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

    當一個對象類型作為收集型對象的元對象時,這個對象應該擁有自己處理equals(),和/或處理hashCode()的設計,而且要遵守前面所說的兩種 原則。equals()先要查null和是否是同一類型。查同一類型是為了避免出現ClassCastException這樣的異常給丟出來。查 null是為了避免出現NullPointerException這樣的異常給丟出來。
    如果你的對象里面容納的數據過多,那么這兩個函數 equals()和hashCode()將會變得效率低。如果對象中擁有無法serialized的數據,equals()有可能在操作中出現錯誤。想象 一個對象x,它的一個整型數據是transient型(不能被serialize成二進制數據流)。然而equals()和hashCode()都有依靠 這個整型數據,那么,這個對象在serialization之前和之后,是否一樣?答案是不一樣。因為serialization之前的整型數據是有效的 數據,在serialization之后,這個整型數據的值并沒有存儲下來,再重新由二進制數據流轉換成對象后,兩者(對象在serialization 之前和之后)的狀態已經不同了。這也是要注意的。

    知道以上這些能夠幫助你:
    1. 進行更好的設計和開發。
    2. 進行更好的測試案例開發。
    3. 在面試過程中讓面試者對你的學識淵博感到滿意。

    posted on 2009-10-31 22:27 草原上的駱駝 閱讀(223) 評論(0)  編輯  收藏 所屬分類: JAVA基礎知識

    主站蜘蛛池模板: 久久精品国产亚洲av麻| 亚洲人片在线观看天堂无码| 七色永久性tv网站免费看| 中文字幕人成人乱码亚洲电影| 特级毛片全部免费播放| 日韩伦理片电影在线免费观看| 亚洲va在线va天堂va手机| 在线精品一卡乱码免费| 亚洲日韩精品射精日| 97在线视频免费公开视频| 亚洲精品午夜无码专区| 青青青国产手机频在线免费观看| 亚洲AV无码久久精品色欲| 久久综合给合久久国产免费| 亚洲黄色在线视频| 在线永久看片免费的视频| 最新亚洲卡一卡二卡三新区| 永久黄网站色视频免费| 深夜a级毛片免费无码| 亚洲色图综合在线| 国产午夜无码片免费| 午夜亚洲www湿好大| 久久久久久精品免费看SSS| 国产日本亚洲一区二区三区| 免费看a级黄色片| 男人扒开添女人下部免费视频| 国产AV无码专区亚洲AV手机麻豆 | 久久ww精品w免费人成| 曰皮全部过程视频免费国产30分钟| 久久亚洲精品11p| 亚洲人成网站在线观看青青| 久久av免费天堂小草播放| 久久亚洲国产精品五月天| www.免费在线观看| 亚洲AV无码专区国产乱码不卡 | 久久久久久国产a免费观看黄色大片 | 9i9精品国产免费久久| 少妇中文字幕乱码亚洲影视| 成年网站免费视频A在线双飞| 欧洲亚洲国产精华液| 国产亚洲?V无码?V男人的天堂|