Java集合-Set
點擊關(guān)注,與你共同成長!

Java集合-Set
Set(java.util.Set)接口,Set中存放的一組沒有重復(fù)數(shù)據(jù)的集合,換句話說,同樣的元素在Set中只能出現(xiàn)一次。Set接口是一個標(biāo)準(zhǔn)的JAVA接口,是Collection的子類,所以Set繼承了Collection 的所有特性。可以向Set中添加任何java對象,如果Set不是類型化的,沒有使用Java泛型,那么您甚至可以在同一個集合中混合不同類型(類)的對象,實際開發(fā)中很少這么做。
Set和List
Set和List非常相似,兩個接口都代表著元素的集合,但是也有一些明顯的不同。這些差異反映在Set和List接口包含的方法中 ,List中可以存在相同的元素,而Set中不允許有重復(fù)的元素。第二個不同是,Set中的元素是沒有順序的,List中的元素是有順序的,List可以按順序進(jìn)行迭代。
Set的例子
下面是簡單的Set例子:
package com.jenkov.collections;
import java.util.HashSet;
public class SetExample {
public static void main(String[] args) {
Set setA = new HashSet();
String element = “123”;
setA.add(element);
System.out.println( setA.contains(element) );
}
}
上面例子創(chuàng)建一個HashSet,HashSet是Set接口的一個實現(xiàn),然后往里面添加一個String對象的元素,添加完后檢查是否包含此元素。
Set的實現(xiàn)
作為Collection 子類型,Collection 接口中的所有方法在Set接口中也可用。既然Set是個接口,實例化時就要使用具體的實現(xiàn)類。可以選擇下面幾個Collections API中的實現(xiàn):
java.util.EnumSet java.util.HashSet java.util.LinkedHashSet java.util.TreeSet
在迭代集合時,每一個集合實現(xiàn)在元素的順序以及在集合中插入和訪問元素所需的時間(big O表示法)方面的行為都略有不同。HashSet由HashMap支持,它不保證迭代元素時元素的順序。LinkedHashSet 和HashSet 是不一樣的,LinkedHashSet 可以保證元素的順序與添加元素時的順序一樣,重新插入LinkedHashSet中已存在的元素不會更改此順序。TreeSet 同樣可以保證元素的迭代順序,但是元素的順序是排序后的順序,換句話就是順序是調(diào)用了 Collections.sort() 后的順序,這個順序由它們的自然順序決定(如果它們實現(xiàn)了Comparable的話),或者由一個特定的Comparator 實現(xiàn)來確定。Set在java.util.concurrent中也有一些實現(xiàn)類,這個以后會講述。
創(chuàng)建Set
下面是創(chuàng)建 Set實例:
package com.jenkov.collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;
public class SetExample {
public static void main(String[] args) {
Set setA = new HashSet();
Set setB = new LinkedHashSet();
Set setC = new TreeSet();
}
}
Set的泛型
默認(rèn)可以在Set中添加Object,Java5以后新加了泛型,可以限制Set集合中的數(shù)據(jù)類型,下面是例子:
Set<MyObject> set = new HashSet<MyObject>();
Set中只能添加MyObject實例對象,訪問或者迭代時不需要強(qiáng)制類型轉(zhuǎn)換:
for(MyObject anObject : set){
//do someting to anObject...
}
Set添加元素
可以通過add()方法向Set中添加元素,這個方法繼承自Collection.下面是例子:
Set<String> setA = new HashSet<>();
setA.add("element 1");
setA.add("element 2");
setA.add("element 3");
調(diào)用了三次add()方法。
迭代Set元素
有兩種方法迭代Set:
使用Iterator迭代 Set 使用 for-each 循環(huán)
這兩種方法下面都會講述,迭代元素的順序取決于使用的Set實現(xiàn)類。
使用Iterator迭代Set
使用Iterator迭代Set,首先需要從Set中獲取Iterator,下面是例子:
Set<String> setA = new HashSet<>();
setA.add("element 1");
setA.add("element 2");
setA.add("element 3");
Iterator<String> iterator = set.iterator();
while(iterator.hasNext(){
String element = iterator.next();
}
使用For-Each循環(huán)迭代Set
第二種方式是使用for-each循環(huán)迭代Set,下面是代碼:
Set set = new HashSet();
for(Object object : set) {
String element = (String) object;
}
Set接口實現(xiàn)了Iterable接口,所以Set可以使用for-each循環(huán)迭代,如果Set使用了泛型,那么迭代循環(huán)內(nèi)部可以使用泛型的類型 :
Set<String> set = new HashSet<>();
for(String str : set) {
System.out.println(str);
}
使用Stream API迭代Set
第三種方式是使用 Stream API迭代Set ,迭代時必須從Set中獲取Stream,下面是代碼:
Set<String> set = new HashSet<>();
set.add("one");
set.add("two");
set.add("three");
Stream<String> stream = set.stream();
stream.forEach((element) -> { System.out.println(element); });
從Set中移除元素
可以通過Set的remove(Object o)方法,從Set中移除一個元素,下面是例子:
set.remove("object-to-remove");
沒有辦法更加Set的索引刪除元素,因為元素的順序取決于Set的具體實現(xiàn)。
從Set中移除所有元素
可以調(diào)用Set的clear()方法,移除Set中所有的元素:
set.clear();
將另外一個集合的所有元素加到Set中
List接口中一個addAll()方法,可以增加 另一個 Collection (List或者Set)中的所有元素到 Set中,Set中也有對應(yīng)的方法:
Set<String> set = new HashSet<>();
set.add("one");
set.add("two");
set.add("three");
Set<String> set2 = new HashSet<>();
set2.add("four");
set2.addAll(set);
代碼執(zhí)行后,set2中包含的元素是one,two , three 和four 。
移除另外一個集合在本集合中存在的所有元素
Set接口中存在removeAll()方法,就移除本集合和給定的Collection中同時存在的元素,在集合論中,這被稱為集合與其他集合之間的區(qū)別,下面是代碼:
Set<String> set = new HashSet<>();
set.add("one");
set.add("two");
set.add("three");
Set set2 = new HashSet();
set2.add("three");
set.removeAll(set2);
執(zhí)行完代碼后,set中包含的元素是one 和 two。元素three被移除,因為在set和set2中都存在。
保留兩個集合中同時存在的元素
Set接口同樣也有保留兩個集合中同時存在的元素,也就是兩個集合的交集 :
Set<String> set = new HashSet<>();
set.add("one");
set.add("two");
set.add("three");
Set<String> set2 = new HashSet<>();
set2.add("three");
set2.add("four");
set.retainAll(set2);
執(zhí)行完代碼后,set中只包含了three元素,因為只有這個元素同時存在set和set2中。
Set大小
可以通過Set的size()方法查看Set的大小:
Set<String> set = new HashSet<>();
set.add("123");
set.add("456");
set.add("789");
int size = set.size();
執(zhí)行后,size的值是3,因為Set中已經(jīng)加入了3個元素。
檢查Set是否是空
可以調(diào)用Set的isEmpty()方法,檢查Set是否是空:
Set<String> set = new HashSet<>();
boolean isEmpty = set.isEmpty();
執(zhí)行代碼后isEmpty 的值是空,因為Set中沒有元素。也可以通過Set的size()是否是0來判斷Set是否是空:
Set<String> set = new HashSet<>();
boolean isEmpty = (set.size() == 0);
執(zhí)行代碼后,isEmpty的值是true,因為Set中沒有元素,所以size()的值是0.
Set是否包含某個指定元素
可以通過contains()方法檢查Set中是否包含給定的元素,下面是例子:
Set<String> set = new HashSet<>();
set.add("123");
set.add("456");
boolean contains123 = set.contains("123");
執(zhí)行后contains123的值是true,因為Set中包含字符串123。
為了確定Set中是否包含每個元素,Set內(nèi)部用的equals()方法比較。但是Set中可以添加null值,所以也可以檢查Set中是否包含null:
set.add(null);
containsElement = set.contains(null);
System.out.println(containsElement);
顯然,contains()的參數(shù)是null, contains()方法比較不使用的==而不是equals()。
將Set轉(zhuǎn)成List
可以通過 List 的 addAll()方法,將Set轉(zhuǎn)成List
Set<String> set = new HashSet<>();
set.add("123");
set.add("456");
List<String> list = new ArrayList<>();
list.addAll(set);
執(zhí)行后,List中包含 123 和 456。

以上,便是今天的分享,希望大家喜歡,覺得內(nèi)容不錯的,歡迎「分享」「贊」或者點擊「在看」支持,謝謝各位。
