承接上次的博客 這次要分享的是我在《瘋狂java筆記》中對于HashSet類的知識獲取
HashSet是set接口的典型實現,大多時候是用的set集合就是HashSet,HashSet按照Hash算法來存儲集合中的元素,具有很好的查詢和存取性能。
HashSet具有以下特點
不能保證元素的排列順序,順序與添加順序可能不同,并且會很混亂HashSet不是同步的,多線程訪問HashSet要保證其同步性幾何元素可以為nullHashSet集合判斷兩個元素相等的標準是兩個對象的equals()方法比較性等,而且兩個對象的hashCode()方法返回值也相等。
hashSet判斷集合元素相等的標準代碼塊:
//重寫A類中equals的方法使其總是返回trueclass A{ @Override public boolean equals(Object obj) { return true; }}//重寫B類中的hashcode方法使其總是返回1class B{ @Override public int hashCode() { return 1; }}//重寫C類中的equals和hashCode方法使其分別返回true和2class C{ @Override public boolean equals(Object obj) { return true; } @Override public int hashCode() { return 2; }}public class HashSet { public static void main(String[] args) { java.util.HashSet books = new java.util.HashSet(); books.add(new A()); books.add(new A()); books.add(new B()); books.add(new B()); books.add(new C()); books.add(new C()); System.out.PRintln(books); }}**運行結果為: [com.HashSet.B@1, com.HashSet.B@1, com.HashSet.C@2, com.HashSet.A@74a14482, com.HashSet.A@4554617c]**
注:兩個A對象的equals()方法比較相等,但是這兩個的hashCode值不同,HashSet將其當成兩個對象存儲在hash表的不同位置,兩個B對象的hashCode值雖然相等但是,但由于未重寫equals方法,故兩個B對象是被HashSet當成兩個對象存儲在hash標的不同位置,但這時對于Hash表來說是比較麻煩的,Hash表會在同一個用鏈式結構保存多個對象,如果hashSet中兩個以上的元素擁有相同的hashCode,將會導致性能下降。C對象雖然在books集合中添加了兩個對象,但由于其equals比較和hashCode比較都相同,故hashSet認為是一個相同的元素,個只能添加一個成功,所以控制臺輸出的結果只有5個。
hash算法可以根基元素的hashCode值直接計算出元素的存儲位置,從而快速定位出該元素。表面看氣來HashSet集合中的元素沒有索引,實際上由hashCode計算出來的存儲位置值可以認定為一個索引,HashSet對比數組來說:數組的長度是固定的,索引是連續的,且不能隨意增加數組的長度,但HashSet在這些方面做出的很出色
重寫hashCode()方法的基本規則:
程序運行過程中,同一個對象多次調用hashCode()方法應該返回相同的值當兩個對象的equals方法比較返回True時,這兩個對象的hashCode返回的值應該相等對象中用作equals方法比較標準的實例變量,都應該用于計算hashCode值重寫hashCode方法的一般步驟:
把對象內每個有意義的實例變量(即每個參與equals方法比較標準的實例變量)計算出一個int類型的hashCode值計算方式如下:最后請大家注意:當向HashSet中添加可變對象時,必須十分小心。如果修改HashSet中的元素的話與集合中的其他對象相等,從而導致HashSet無法準確訪問該對象。
謝謝大家捧場。
新聞熱點
疑難解答