java中hashCode辦法與equals辦法的用法總結。本站提示廣大學習愛好者:(java中hashCode辦法與equals辦法的用法總結)文章只能為提供參考,不一定能成為您想要的結果。以下是java中hashCode辦法與equals辦法的用法總結正文
起首,想要明確hashCode的感化,必需要先曉得Java中的聚集。
總的來講,Java中的聚集(Collection)有兩類,一類是List,再有一類是Set。 前者聚集內的元素是有序的,元素可以反復;後者元素無序,但元素弗成反復。
那末這裡就有一個比擬嚴重的成績了:要想包管元素不反復,可兩個元素能否反復應當根據甚麼來斷定呢? 這就是Object.equals辦法了。然則,假如每增長一個元素就檢討一次,那末當元素許多時,後添加到聚集中的元素比擬的次數就異常多了。 也就是說,假如聚集中如今曾經有1000個元素,那末第1001個元素參加聚集時,它就要挪用1000次equals辦法。這明顯會年夜年夜下降效力。
因而,Java采取了哈希表的道理。哈希(Hash)現實上是小我名,因為他提出一哈希算法的概念,所以就以他的名字定名了。 哈希算法也稱為散列算法,是將數據依特定算法直接指定到一個地址上。初學者可以如許懂得,hashCode辦法現實上前往的就是對象存儲的物理地址(現實能夠其實不是)。
如許一來,當聚集要添加新的元素時,先挪用這個元素的hashCode辦法,就一會兒能定位到它應當放置的物理地位上。 假如這個地位上沒有元素,它便可以直接存儲在這個地位上,不消再停止任何比擬了;假如這個地位上曾經有元素了, 就挪用它的equals辦法與新元素停止比擬,雷同的話就不存了,不雷同就散列其它的地址。 所以這裡存在一個抵觸處理的成績。如許一來現實挪用equals辦法的次數就年夜年夜下降了,簡直只須要一兩次。
所以,Java關於eqauls辦法和hashCode辦法是如許劃定的:
1、假如兩個對象雷同,那末它們的hashCode值必定要雷同;
2、假如兩個對象的hashCode雷同,它們其實不必定雷同(下面說的對象雷同指的是用eqauls辦法比擬。)
你固然可以不按請求去做了,但你會發明,雷同的對象可以湧現在Set聚集中。同時,增長新元素的效力會年夜年夜降低。
hashcode這個辦法是用來判定2個對象能否相等的。 那你會說,不是還有equals這個辦法嗎? 不錯,這2個辦法都是用來斷定2個對象能否相等的。然則他們是有差別的。 普通來說,equals這個辦法是給用戶挪用的,假如你想斷定2個對象能否相等,你可以重寫equals辦法,然後在代碼中挪用,便可以斷定他們能否相等 了。簡略來說,equals辦法重要是用來斷定從外面上看或許從內容上看,2個對象是否是相等。
舉個例子,有個先生類,屬性只要姓名和性別,那末我們可以 以為只需姓名和性別相等,那末就說這2個對象是相等的。 hashcode辦法普通用戶不會去挪用,好比在hashmap中,因為key是弗成以反復的,他在斷定key是否是反復的時刻就斷定了hashcode 這個辦法,並且也用到了equals辦法。這裡弗成以反復是說equals和hashcode只需有一個不等便可以了!所以簡略來說,hashcode相 當因而一個對象的編碼,就似乎文件中的md5,他和equals分歧就在於他前往的是int型的,比擬起來不直不雅。我們普通在籠罩equals的同時也要 籠罩hashcode,讓他們的邏輯分歧。舉個例子,照樣方才的例子,假如姓名和性別相等就算2個對象相等的話,那末hashcode的辦法也要前往姓名 的hashcode值加上性其余hashcode值,如許從邏輯上,他們就分歧了。 要從物理上斷定2個對象能否相等,用==便可以了。
在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. 在面試進程中讓面試者對你的學問廣博覺得滿足。