set集合中存放的數據有一個特點,那就是無序且不重復。無序是因為set集合中的元素沒有下坐標。不重復的原因就是因為set集合中有hashcode與equals這兩個方法。
一、 要想保證元素不重復,可兩個元素是否重復應該依據什么來判斷呢?這就是Object.equals方法了。但是,如果每增加一個元素就檢查一次,那么當元素很多時,后添加到集合中的元素比較的次數就非常多了。也就是說,如果集合中現在已經有1000個元素,那么第1001個元素加入集合時,它就要調用1000次equals方法。這顯然會大大降低效率。于是,Java采用了哈希表的原理。哈希(Hash)實際上是個人名,由于他提出一哈希算法的概念,所以就以他的名字命名了。哈希算法也稱為散列算法,是將數據依特定算法直接指定到一個地址上。hashCode方法實際上返回的就是對象存儲的物理地址。這樣一來,當集合要添加新的元素時,先調用這個元素的hashCode方法,就一下子能定位到它應該放置的物理位置上。如果這個位置上沒有元素,它就可以直接存儲在這個位置上,不用再進行任何比較了;如果這個位置上已經有元素了,就調用它的equals方法與新元素進行比較,相同的話就不存了,不相同就散列其它的地址。所以這里存在一個沖突解決的問題。這樣一來實際調用equals方法的次數就大大降低了,幾乎只需要一兩次。所以,Java對于eqauls方法和hashCode方法是這樣規定的:1、如果兩個對象相同,那么它們的hashCode值一定要相同;2、如果兩個對象的hashCode相同,它們并不一定相同上面說的對象相同指的是用eqauls方法比較。你當然可以不按要求去做了,但你會發現,相同的對象可以出現在Set集合中。同時,增加新元素的效率會大大下降。
主要看二、set集合中存放數據的步驟。
step1:程序向HashSet中添加一個對象時,先用hashCode方法計算出該對象的哈希碼。
step2:比較:(1),如果該對象哈希碼與集合已存在對象的哈希碼不一致,則該對象沒有與其他對象重復,添加到集合中!
? ? ? ? ? ? ? ? ? ? ? ? ? ?(2),如果存在于該對象相同的哈希碼,那么通過equals方法判斷兩個哈希碼相同的對象是否為同一對象(判斷的標準是:屬性是否相同)
1>,相同對象,不添加。
2>,不同對象,添加!
三、算是總結吧。
hashCode不同時,則必為不同對象。hashCode相同時,根據equlas()方法判斷是否為同一對象。