set集合能夠存儲多個對象,但並不會記住元素的存儲順序,也不容許集合中有重複元素(不一樣的set集合有不一樣的判斷方法)。java
1.HashSet類算法
HashSet按照Hash算法存儲集合中的元素,具備很好的存取和查找性能。當向HashSet中添加一些元素時,HashSet會根據該對象的HashCode()方法來獲得該對象的HashCode值,而後根據這些HashCode的值來決定元素的位置。性能
HashSet的特色:1.存儲順序和添加的順序不一樣this
2.HashSet不是同步的,若是多個線程同時訪問一個HashSet,假設有兩個或更多的線程修改了集合中的值,則必須經過代碼使線程同步。es5
3.HastSet容許集合中的元素爲null。spa
在HashSet集合中,判斷兩個元素相同的標準是:兩個對象經過equals()方法相等,且HashCode()方法的返回值也相等。若是有兩個元素經過equals()方法比較相等,而HashCode()的返回值不一樣,HashSet會將這兩個對象保存在不一樣的地方。線程
注意:若是向HashSet中添加一個可變對象後,後面的對象修改了該可變對象的實例變量,則可能致使它與集合中的其餘元素相同。設計
class R{ int count; public R(int count){ this.count= count; } public String toString(){ return "R[count:" + count + "]"; } public boolean equals(Object obj){ if (this == obj) return true; if (obj != null && obj.getClass() == R.class) { R r = (R)obj; return this.count == r.count; } return false; } public int HashCode(){ return this.count; } } public class HashSetTest { public static void main(String[] args){ HashSet hs = new HashSet(); hs.add(new R(5)); hs.add(new R(-3)); hs.add(new R(9)); hs.add(new R(-2)); //輸出:[R[count:9], R[count:5], R[count:-3], R[count:-2]] System.out.println(hs); Iterator it = hs.iterator(); R first = (R)it.next(); first.count = -3; //輸出:[R[count:-3], R[count:5], R[count:-3], R[count:-2]] System.out.println(hs); //輸出:是否包含count爲-3的對象:false System.out.println("是否包含count爲-3的對象:" + hs.contains(new R(-3))); //輸出:是否包含count爲-2的對象:false System.out.println("是否包含count爲-2的對象:" + hs.contains(new R(-2))); } }
這個例子中代碼first.count=-3改變了集合中的實例變量,在應該count爲9的地方放入了count爲-3的元素,致使HashSet不能準確訪問元素。在判斷其餘元素也會出錯,好比判斷集合是否包含-2,-3.rest
(上面這句話是我本身理解的,總感受不太對,你們幫我看看)code
2.LinkedHashSet類
LikedHashSet是HashSet的子類,它也是根據元素的HashCode值進來決定元素的存儲位置,但它可以同時使用鏈表來維護元素的添加次序,使得元素能以插入順序保存。
public class LinkHashSetTest { public static void main(String[] args){ LinkedHashSet lh = new LinkedHashSet(); lh.add(1); lh.add(2); lh.add(3); //輸出:[1, 2, 3] System.out.println(lh); lh.remove(1); lh.add(1); //輸出:[ 2, 3 ,1] System.out.println(lh); } }
3.TreeSet
TreeSet是SortedSet接口的實現類,TreeSet能夠保證了集合元素處於排序狀態(所謂排序狀態,就是元素按照必定的規則排序,好比升序排列,降序排列)。
與HashSet集合相比。
Comparator comparator():若是TreeSet採用了定製排序,則該方法返回定製排序所使用的Comparator,若是採用了天然排序,則返回null。
Object first(): 返回集合中的第一個元素。
Object last():返回集合中的最後一個元素。
Object lower(Object e):返回集合中位於指定元素e以前的元素(即小於指定元素的最大元素,參考元素e沒必要是集合中的元素)。
Object higher(Object e): 返回集合中位於指定元素e以後的元素(即大於指定元素的最小元素,參考元素e沒必要是集合中的元素)。
SortedSet subSet(Object fromElement, Object toElement): 返回集合中全部在fromElemt和toElement之間的元素(包含fromElent自己,不包含toElement自己)。
SortedSet headSet(Object toElement): 返回此set的子集,由小於toElement的元素組成。
SortedSet tailSet(Object fromElement):返回此set的子集,由大於或等於fromElement的元素組成。
public class TreeSetTest { public static void main(String[] args){ TreeSet ts = new TreeSet(); ts.add(5); ts.add(2); ts.add(10); ts.add(-9); //輸出:null 證實是天然排序 System.out.println(ts.comparator()); //輸出:-9 System.out.println(ts.first()); //輸出:10 System.out.println(ts.last()); //輸出:2 System.out.println(ts.lower(3)); //輸出:10 System.out.println(ts.higher(5)); //輸出[5, 10] System.out.println(ts.subSet(3, 12)); //輸出:[-9, 2, 5] System.out.println(ts.headSet(10)); //輸出:[5, 10] System.out.println(ts.tailSet(5)); } }
TreeSet支持兩種排序方法:天然排序和定製排序。在默認的狀況下,TreeSet採用天然排序。
天然排序:TreeSet會調用集合元素的compareTo(Object obj)方法來比較元素之間的大小關係,而後讓集合按照升序排列,這種方式叫作天然排序。
定製排序:定製排序是按照使用者的要求,須要本身設計的一種排序。若是須要定製排序,好比須要數據按照降序排列,則能夠經過Comparator接口的幫助。
PS:
1.若是但願TreeSet可以正常運行,TreeSet只能添加同一種類型的對象。
2.TreeSet集合中判斷元素相等的惟一標準是:兩個對象經過comparator(Object obj)方法比較後,返回0;不然認爲不相等。
3.EnumSet類
EnumSet類是一種專爲枚舉類設計的集合類,EnumSet中的全部元素都必須是指定枚舉類型的枚舉值,該枚舉類型在建立EnumSe類時顯式或隱式的指定。EnumSet的集合元素也是有序的,EnumSet以枚舉值在Enum類內的定義順序來決定集合元素的順序。
EnumSet提供了以下經常使用的類方法來建立EnumSet對象:
EnumSet allOf(Class elementType): 建立一個包含指定枚舉類中的全部枚舉值的EnumSet集合。
EnumSet complement(EnumSet s):建立一個其元素類型與指定EnumSet裏元素類型相同的EnumSet集合,新的EnumSet集合包含原來的EnumSet集合所不包含的,此枚舉類剩下的枚舉值(新的EnumSet集合加上原EnumSet集合中的集合元素就是該枚舉類中全部的枚舉值)。
EnumSet copyOf(Collection c): 使用一個普通集合來建立EnumSet集合。
EnumSet copyOf(EnumSet s): 建立一個和指定EnumSet集合,同類型同集合元素的EnumSet集合。
EnumSet noneOf(Class elementType): 建立一個元素類型是指定枚舉類型的空EnumSet集合。
EnumSet of(E first, E... rest): 建立一個包含一個或者多個枚舉值得EnumSet集合,傳入的枚舉值必須屬於同一個枚舉類。
EnumSet range(E from, E to):建立一個從from枚舉值到to枚舉值範圍內全部枚舉值的EnumSet集合。
enum Season{ SPRING,SUMMER,FALL,WINTER } public class EnumSetTest { public static void main(String[] args){ EnumSet es1 = EnumSet.allOf(Season.class); //輸出:[SPRING, SUMMER, FALL, WINTER] System.out.println(es1); EnumSet es2 = EnumSet.noneOf(Season.class); //輸出:[] System.out.println(es2); es2.add(Season.WINTER); es2.add(Season.SPRING); //輸出:[SPRING, WINTER] System.out.println(es2); EnumSet es3 = EnumSet.of(Season.SPRING, Season.WINTER); //輸出:[SPRING, WINTER] System.out.println(es3); EnumSet es4 = EnumSet.range(Season.SPRING, Season.WINTER); //輸出:[SPRING, SUMMER, FALL, WINTER] System.out.println(es4); EnumSet es5 = EnumSet.complementOf(es4); //輸出:[] System.out.println(es5); } }
------------《瘋狂java講義》8.3set集合