JAVA api (Set介面,HashSet與TreeSet的作用和實現)
set
Set作為和List並列的介面同樣繼承了父類的各種方法,同時也有屬於自己的特性。
set的底層是以雜湊表的形式存在的,也就是散列表,它的特點:
1、一個不包含重複元素的 collection。
2、資料無序(因為set集合沒有下標)。
3、由於集合中的元素不可以重複。常用於給資料去重。
4、可以存入一個null
Set<Integer> s = new HashSet<Integer>();
s.add(1);
s.add(4);
s.add(3);
s.add(2);
System. out.println(s);
它的輸出結果是:[1, 2, 3, 4]
該介面繼承於Collerction並且沒有自己的獨特方法,我也就不再過多贅述了。
HashSet與TreeSet
HashSet是Set的實現類,並沒有什麼特殊的方法,由於它繼承於Set,同樣由雜湊表來實現,由此它並不能保證set的迭代順序,並且不能保證這個順序是一成不變的。此類允許使用null元素。
在這裡我們並不會寫入太多的程式碼,但是我們可以來分析一下原始碼:
我們來看HashSet的無參構造方法:
public HashSet() {
map = new HashMap<>( );
}
我們發現這個類實際上是在底層維護了一個HashMap類。
這個咱們不在本章過多贅述,後續會有專門講解的章節。
但是由此我們是不是可以說TreeSet底層維護了一個TreeMap類呢?
public TreeSet() {
this(new TreeMap<E,Object>());
}
看TreeSet的構造方法,我們可以發現確實如此…
去重的方式
引用到堆上同一個物件的兩個引用是相等的。如果對兩個引用呼叫hashCode方法,會得到相同的結果,如果物件所屬的類沒有覆蓋Object的hashCode方法的話,hashCode會返回每個物件特有的序號(java是依據物件的記憶體地址計算出的此序號),所以兩個不同的物件的hashCode值是不可能相等的。如果想要讓兩個不同的Person物件視為相等的,就必須覆蓋Object繼下來的hashCode方法和equals方法,因為Object hashCode方法返回的是該物件的記憶體地址,所以必須重寫hashCode方法,才能保證兩個不同的物件具有相同的hashCode,同時也需要兩個不同物件比較equals方法會返回true。
看下圖:
本章似乎並沒有講述什麼,但是事實上set的作用往往用於去重,在學習工程中我也沒有發現什麼用處…如果後續有用會做一補充。