集合原始碼分析(四)HashSet集合

2021-08-28 13:47:34 字數 2958 閱讀 6423

//無序、無索引、不可以重複。

a:存入集合的順序和取出集合的順序不一致

b:沒有索引

c:存入集合的元素不能重複

使用hashset集合注意點:重寫hashcode和equals方法。

呼叫順序:

規則:新新增到hashset集合的元素都會與集合中已有的元素一一比較。

首先比較雜湊值(每個元素都會呼叫hashcode()產生乙個雜湊值)。

如果新新增的元素與集合中已有的元素的雜湊值都不同,新新增的元素存入集合。

如果新新增的元素與集合中已有的某個元素雜湊值相同,此時還需要呼叫equals(object obj)比較。

如果equals(object obj)方法返回true,說明新新增的元素與集合中已有的某個元素的屬性值相同,那麼新新增的元素不存入集合。

如果equals(object obj)方法返回false, 說明新新增的元素與集合中已有的元素的屬性值都不同, 那麼新新增的元素存入集合。

//如果用arraylist實現hashset去除重複的功能?

如果用arraylist實現hashset的去除重複的功能

方法一:

arraylistal1 = new arraylist<>();

al1.add("a");

al1.add("a");

al1.add("b");

al1.add("b");

al1.add("c");

al1.add("c");

arraylistal2 = new arraylist<>();

for (string string : al1)

} system.out.println(al2);

al1.clear();

al1.addall(al2);

system.out.println(al1);

}

方法二://物件導向的思想。

自己定義乙個myarraylist類,繼承arraylist。重寫裡面的add方法,也可以。

hashset實現set介面,由雜湊表(實際上是乙個hashmap例項)支援。它不保證set 的迭代順序;特別是它不保證該順序恆久不變,此類允許使用null元素。在hashset中,元素都存到hashmap鍵值對的key上面,而value時有乙個統一的值private static final object present = new object();

所以set 集合底層依賴的是 map 雙列集合的鍵,值為 new object();

即:add方法原始碼:

public boolean add(e e)

set集合新增實際上是新增到map集合中鍵的位置,值為present。而present = new object();

因為沒有索引,所有set集合的遍歷只能使用迭代器和增強for。

遍歷一:

hashseths = new hashset<>();

hs.add("a");

hs.add("b");

hs.add("c");

iteratorit = hs.iterator();

while(it.hasnext())

遍歷二:

hashset它的內部是根據equals()返回值和hashcode()的值是否相同兩個方法來判斷兩個物件是否相同的。而源**上,hashset內部用了乙個hashmap作儲存,add()方法內是呼叫了map的put()方法,map的put()方法會檢查這個鍵是否已存在,若是則返回該鍵之前的值,並更新成新值,若不是則返回null,但這個鍵是不會發生改變的。所以,在源**裡,hashset的add()方法是根據map的put返回值來判斷新增元素是否成功的。

hash集合在操作不當的情況下,有可能造成記憶體洩漏。

考慮這樣的情況,把乙個物件儲存進hashset集合後,修改這個物件中參與計算hash的變數的值,這時這個物件的hash值也會隨之改變,那麼這麼物件可以正常地被刪除嗎?下面用**試一下:

先自定乙個mpoint類,其中有兩個變數,x和y,其中x參與計算hash值

public class mpoint 

public mpoint( int x, int y)

public int getx()

public void setx(int x)

public int gety()

public void sety(int y)

@override

public int hashcode()

@override

public boolean equals(object obj)

}

主函式類測試,在乙個hashset集合中:新增三個元素,mp1、mp2、***,並進行其中屬性的修改和輸出測試

public class hashsettest 

}

輸出結果如下:

2

2false

false

true

true

1

可以看出已經發生了記憶體洩漏了,mp1物件不能被正常刪除。

HashSet原始碼分析

基於hashmap的set介面實現。它不保證集合的迭代順序。特別是,它不能保證順序會隨著時間的推移保持恆定,當擴容時順序將調整。此類允許null元素。建立的hashmap private transient hashmap map 因為底層使用hashmap實現,要存key,value,這個固定值就...

HashSet原始碼分析總結

hashset實現set介面,由雜湊表 實際上是乙個hashmap例項 支援。它不保證set 的迭代順序 特別是它不保證該順序恆久不變。此類允許使用null元素。hashset中的元素實際上取得是hashmap節點中的key,因為hashmap中的key具有唯一性,故而hashset中的元素值不可重...

Java原始碼分析之HashSet

hashset的本質,其實就是hashmap private transient hashmapmap hashmap是鍵值對,而hashset是單值,所以需要乙個值來充當鍵值對中的值 private static final object present new object public has...