HashSet,TreeSet,LinkedHashSet 的用法和區別

Set接口

Set不允許包含相同的元素,如果試圖把兩個相同元素加入同一個集合中,add方法返回false。

使用add()方法添加時,允許添加不會報錯,但是在set中只會存在一個元素。

Set判斷兩個對象相同不是使用==運算符,而是根據equals方法。也就是說,只要兩個對象用equals方法比較返回true,Set就不 會接受這兩個對象。


HashSet
HashSet有以下特點
不能保證元素的排列順序,順序有可能發生變化
不是同步的
集合元素可以是null,但只能放入一個null
當向HashSet結合中存入一個元素時,HashSet會調用該對象的hashCode()方法來得到該對象的hashCode值,然後根據 hashCode值來決定該對象在HashSet中存儲位置。
簡單的說,HashSet集合判斷兩個元素相等的標準是兩個對象通過equals方法比較相等,並且兩個對象的hashCode()方法返回值相 等
注意,如果要把一個對象放入HashSet中,重寫該對象對應類的equals方法,也應該重寫其hashCode()方法。其規則是如果兩個對 象通過equals方法比較返回true時,其hashCode也應該相同。另外,對象中用作equals比較標準的屬性,都應該用來計算 hashCode的值。


LinkedHashSet

LinkedHashSet集合同樣是根據元素的hashCode值來決定元素的存儲位置,但是它同時使用鏈表維護元素的次序。這樣使得元素看起 來像是以插入順序保存的,也就是說,當遍歷該集合時候,LinkedHashSet將會以元素的添加順序訪問集合的元素。
LinkedHashSet在迭代訪問Set中的全部元素時,性能比HashSet好,但是插入時性能稍微遜色於HashSet。

TreeSet類
TreeSet是SortedSet接口的唯一實現類,TreeSet可以確保集合元素處於排序狀態。TreeSet支持兩種排序方式,自然排序 和定製排序,其中自然排序爲默認的排序方式。向TreeSet中加入的應該是同一個類的對象。
TreeSet判斷兩個對象不相等的方式是兩個對象通過equals方法返回false,或者通過CompareTo方法比較沒有返回0
自然排序
自然排序使用要排序元素的CompareTo(Object obj)方法來比較元素之間大小關係,然後將元素按照升序排列。
Java提供了一個Comparable接口,該接口裏定義了一個compareTo(Object obj)方法,該方法返回一個整數值,實現了該接口的對象就可以比較大小。
obj1.compareTo(obj2)方法如果返回0,則說明被比較的兩個對象相等,如果返回一個正數,則表明obj1大於obj2,如果是 負數,則表明obj1小於obj2。
如果我們將兩個對象的equals方法總是返回true,則這兩個對象的compareTo方法返回應該返回0
定製排序
自然排序是根據集合元素的大小,以升序排列,如果要定製排序,應該使用Comparator接口,實現 int compare(T o1,T o2)方法


--------------------------分割線------------------------------


測試插入效率

package Collection_deep;


import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;


public class RepeatSet {
static Set addSet(Set s){
long start = System.currentTimeMillis();
for(int i=0;i<10000;i++){
Random r = new Random();
s.add(r.nextInt(10000));
}
long ContinuedTime = System.currentTimeMillis()-start;
System.out.println("執行插入10000次操作:"+s.getClass().getSimpleName()+"花費時長爲:"+ContinuedTime);
long startRead = System.currentTimeMillis();
Iterator i = s.iterator();
while(i.hasNext()){
i.next();
}
long readTime = System.currentTimeMillis()-startRead;;
System.out.println("執行讀取10000次操作:"+s.getClass().getSimpleName()+"花費時長爲:"+readTime);

return s;



public static void main(String[] args) {
System.out.println("---------------");
addSet(new HashSet());
System.out.println("---------------");
addSet(new TreeSet());
System.out.println("---------------");
addSet(new LinkedHashSet());
System.out.println("---------------");
}


}

測試結果


通過結果可以明顯看到,在執行插入操作時,LinkedHashSet和HashSet執行速度相對較快,而TreeSet的速度爲最慢;

這裏面需要說明的是,

hashset實現Set接口,查詢速度快,爲快速查找而設計的Set,存入hashSet元素必須定義hashCode;

linkedSet也實現Set接口,具有hashSet的查詢速度,而linkedlist是保持次序的set,內部使用鏈表來維護元素的插入順序。

treeSet 實現的接口爲NavigableSet,同時NavigableSet又繼承子SortedSet,所以treeSet底層爲樹結構,可以保證插入元素按順序排列。

-----------------------------分割線--------------------------------

這裏需要註明的是,

SortedSet是個接口,它裏面的(只有TreeSet這一個實現可用)中的元素一定是有序的。
 保證迭代器按照元素遞增順序遍歷的集合,可以按照元素的自然順序(參見 Comparable)進行排序, 或者按照創建有序集合時提供的 Comparator進行排序。



方法測試代碼:


package Collection_deep;


import java.util.Random;
import java.util.SortedSet;
import java.util.TreeSet;


public class SortSetDemo {


public static void main(String[] args) {
SortedSet<Integer>  ss = new TreeSet<Integer>();
for(int i = 0;i<1000;i++){
int j = new Random().nextInt(10);
ss.add(j);
}
System.out.println(ss);
System.out.println(ss.subSet(0, 10));//截取set  包含0開始 不包含第10位結束
System.out.println(ss.first());//set的第一個元素
System.out.println(ss.last());//set的最後一個元素
System.out.println(ss.headSet(10));//從第一位到第10爲元素
System.out.println(ss.tailSet(10));//從第10位(包含第10位元素)到最後
System.out.println(ss.comparator());//返回NULL表示以自然排序,否則返回當前set使用的Co'm'pa'rator
}
}

運行結果:




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章