Set\HashSet集合為什么能去重(轉)


如果想查找一個集合中是否包含有某個對象,大概的程序代碼怎樣寫呢?當發現某個元素與要查找的對對象進行equals方法比較的結果相等時,則停止繼續查找並返回肯定的信息,否則返回否定的信息。如果是一個集合中有很多元素,譬如有一萬個元素,並且沒有包含要查找的對象時,則意味着你的程序需要從該集合中取出一萬個元素進行啄一的比較才能得到結論,有人發明了一種hashCode算法,來提高查找的效率,這種方式將集合分成若干個存儲區域,每個對象可以計算出一個哈希碼,可以將哈希碼分組,每組分別對應某個存儲區域,根據一個對象的哈希碼就可以確定該對象應該存儲在哪個區域,

 

 

 

hashSet就是采用哈希算法存儲對象的集合,它內部采用對某個數字n進行取余的方式對哈希碼進行分組的划分對象的存儲區域。Object中的hashCode用來返回對就java對象的哈希碼,從而提高查找的效率。

 

為了保證一個類的實例對象能在HashSet正常存儲,要求這個類的兩個實例對象用equals()方法比較的結果相等時,它們的哈希碼也必須相等,也就是說,如果obj1.equals(obj2)的結果為true,那么一下表達式的結果頁要為true。

obj1.hashCode() == obj2.hashCode()

如果一個類的hashCode()方法沒有遵循上述要求,那么,當這個的兩個實例對象用equals()方法比較的結果相等時,它們本來應該無法同時存儲進Set集合中,但是,如果將它們存儲進HashSet集合中時,由於它們的hashCode()方法的返回值不同,第二個對象首先按哈希碼計算可能會被放進與第一個對象不同的區域中,這樣,它就不可能與第一個對象進行equals方法比較了,也就可能被存儲進HashSet集合中了。Object類的hashCode()方法不能滿足對象被存入到HashSet中的要求,因為它的返回值是通過對象的內存地址推算出來的,同一個對象在程序運行期間的任何時候返回的哈希值都是始終不變的,所以,只要是兩個不同的實例對象,即使它們的equals方法比較結果相等,它們默認的hashCode方法的返回值是不同的。

提示:

(1)通常來說,一個類的兩個實例對象用equals()方法比較的結果相等時,它們的哈希碼也必須相等,但反之則不成立,即euqlas方法比較結果不相等的對象可以有相同的哈希碼,或者說哈希碼相同的兩個對象的equals方法比較的結果可以不等,例如,字符串“BB”和"Aa"的euqals方法比較結果肯定不相等,但它們的hashCode方法返回值卻相等。

(2)當一個對象被存儲進HashSet集合中以后,就不能修改這個對象中的那些參與計算哈希值的字段了,否則,對象修改后的哈希值與最初存儲進HashSet集合中時的哈希值就不同了,在這種情況下,即使在cantains方法使用該對象的當前引用作為的參數去HashSet集合中檢索對象,也將返回找不到對象的結果。這也會導致從HashSet集合中單獨刪除當前對象,從而造成內存泄露。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM