Java中的Set集合

Set集合不容許包含相同的元素,若是試圖把兩個相同的元素加入同一個Set集合裏面,則添加操做失敗,add()方法返回false,且新元素不會被添加入。java

1.HashSet是Set的接口的典型實現,大多數時候使用Set集合就是使用這個實現類,HashSet按Hash算法來存儲集合中的元素,所以具備很好的存取和查找性能。HashSet具備如下特色,不能保證元素的排列順序,可能和添加的順序不一樣;HashSet不是同步的,若是有多個線程同是訪問一個HashSet,則必須經過代碼來保證其同步性;集合元素值能夠是null。當向HashSet集合存入一個元素時,HashSet會調用該對象的hashcode()方法來獲得該對象的hashCode值,而後提供該hashCode值決定該對象在HashSet中的存儲位置。若是有兩個元素經過equals()方法比較返回true,但他們的hashCode()方法返回值不相等,HashSet將會把他們存儲在不一樣的位置,依然能夠添加成功,也就是說HashSet集合判斷兩個元素相等的標準是兩個對象經過equals()方法比較相等,而且兩個對象的hashCode方法返回值也相等。 HashSet中每一個能存儲元素的「槽位」(solt)一般也稱爲「桶」(bucket),若是有多個元素的hashCode值相同,但他們經過的equals()方法比較返回false,就須要在一個「桶」裏面放入多個元素,這就會致使性能的降低。算法

2.HashSet還有一個子類LinkedHashSet,LinkedHashSet集合也是根據元素的hashCode值來決定元素的存儲位置,但它同時使用鏈表維護元素的次序,這樣使得元素看起來是以插入的順序保存的。也就說遍歷LinkedHashSet集合裏的元素時,LinkedHashSet將會按元素的的添加順序來訪問裏的元素。LinkedHashSet須要維護元素的插入順序,所以性能略低於HashSet的性能,但在迭代訪問Set裏的所有元素時將會有很好的性能,由於它以麗鏈表來維護內部順序。安全

package com.lanou.test;

import java.util.LinkedHashSet;
public class Demo10 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		LinkedHashSet<String> linkedHashSet=new LinkedHashSet<String>();
        linkedHashSet.add("zasas");
        linkedHashSet.add("dsakek");
        linkedHashSet.add("adsdsd");
        linkedHashSet.add("zasdkesd");
        System.out.println(linkedHashSet);
	}

}

3.TreeSet是SortedSet接口的實現類,TreeSet能夠確保集合元素處於排序狀態。與HashSet集合相比,TreeSet還提供了幾個額外的方法。Comparator comparator():若是TreeSet採用了定製的順序,該方法返回定製的排序所使用的Comparator:若是TreeSet採用天然排序,則返回null。Object first()返回集合中的一個元素。Object last()返回集合中的最後一個元素。Object lower(Object e):返回集合中位於指定元素以前的元素。Object higher(Object e)返回集合中位於指定元素以後的元素。Sorted subSet(Object formElement,Object toElement)返回次set的子集合,範圍從fromElement(包含)到toElement(不包含)。SortedSet headSet(Object toElement)返回此set的子集合,小於toElement的元素組成。SortedSet tailSet(Object formElement):返回此set的子集合,由大於或等於fromElement的元素組成。函數

package com.lanou.test;

import java.util.TreeSet;
public class Demo11 {
	public static void main(String[] args) {
		TreeSet munber=new TreeSet();
		munber.add(6);
		munber.add(45);
		munber.add(12);
		munber.add(-9);
		System.out.println(munber);
	}
}

其實TreeSet會調用集合元素的comparaTo(Object obj)方法來比較元素之間的大小關係,而後將集合元素按升序排列,這種方式就是天然排序。java還提供了一個Comparable接口,該接口裏面定義一個comparaTo(Object obj)方法,該方法返回一個整數值,實現該接口的類必須實現該方法,實現了該接口的類的對象的就能夠比較大小了。一個對象調用該方法比較另外一個對象大小,若是相等返回0,大於返回正整數。java中經常使用的類已經實現了Comparable接口,有BigDecimal、BIgInteger、Character、Boolean、String、Date、Time。若是但願TreeSet能正常運做時,TreeSet只能添加同一種類型的對象。定製排序TreeSet的天然排序是根據集合元素的大小,TreeSet將他們按照升序排列,如要讓他們實現定製的順序,就要經過Comparator接口,該接口裏麪包含一個int compara(T o1,To2)的方法,該方法用於比較o1和o2的大小,由於Comparator接口是個函數是接口,所以可以使用lanbda 表達式。性能

4.EnumSet是專門爲枚舉設計的集合類,EnumSet中的全部元素都必須是指定枚舉類型的枚舉值,該枚舉在建立EnumSet時顯示或隱式地指定。EnumSet的集合也是有序的,EnumSet以枚舉值在Enum類內的定義順序來決定集合元素的順序。EnumSet在內部以位向量的形式存儲,這種存儲形式很是緊湊、高效、所以EnumSet對象佔用的內存很小,且運行效率很好。EnumSet集合不容許加入null元素,如試圖添加null元素,EnumSet將拋出NullpointException異常。線程

5.HashSet和TreeSet是set的兩個典型實現,HashSet的性能老是比TreeSet好,特別是添加查詢操做,由於TreeSet須要額外的紅黑樹算法來維護集合元素的次序。只要當須要一個保持排序的Set時,纔會用TreeSet,不然都是使用HashSet。HashSet還有個子類LinkedHashSet,對於普通的的插入、刪除操做,LinkedHashSet比HashSet要略慢一點,這是維持鏈表所帶來的額外的開銷,但因爲有鏈表,遍歷LinkedHashSet會更快。EnumSet是全部Set實現類中性能最好的,但它只能保存一個枚舉類的枚舉值做爲集合元素。 Set的三個實現類Hashset TreeSet EnumSet都是線程不安全的。若是有多個線程同時訪問一個Set集合,而且有一個線程修改了該Set的集合類,就必須手動保證該Set集合的同步性,經過synchronizedSortedSet包裝該set集合。設計

相關文章
相關標籤/搜索