Java中Set與Set 到底區別在哪?


您可能知道,無界通配符 Set<?> 可以容納任何類型的元素,而原始類型Set也可以容納任何類型的元素。那它們之間有什么區別呢?

1.關於Set<?>的兩個事實

關於Set<?>有兩個事實:

  • Item 1:?代表任何類型。Set<?> 可以容納任何類型的元素。_
  • Item 2:因為我們不知道?的類型,所以不能將任何元素放入Set<?>。

因此 Set<?> 可以容納任何類型的element(Item 1),但我們不能將任何元素放入其中(Item 2)。這兩個陳述是否彼此沖突?當然不是。以下兩個示例可以清楚地說明這一點:

** Item 1表示以下情況:**

//合法 代碼
public static void main(String[] args) {
	HashSet<Integer> s1 = new HashSet<Integer>(Arrays.asList(1, 2, 3));
	printSet(s1);
 
	HashSet<String> s2 = new HashSet<String>(Arrays.asList("a", "b", "c"));
	printSet(s2);
}
 
public static void printSet(Set<?> s) {
	for (Object o : s) {
		System.out.println(o);
	}
}

由於 Set<?> 可以容納任何類型的元素,因此我們僅在循環中使用Object。

** Item 3是指以下非法情況:**

//非法代碼
public static void printSet(Set<?> s) {
	s.add(10);//this line is illegal 
	for (Object o : s) {
		System.out.println(o);
	}
}

因為我們不完全知道 的類型,所以除了null之外,我們無法添加其他任何內容。出於相同的原因,我們無法使用 Set 初始化集合。以下是非法的:

//非法代碼 
Set<?> set = new HashSet<?>();

2.Set 與 Set<?>

原始類型集和無界通配符集<?>有什么區別?

此方法聲明很好:

public static void printSet(Set s) {
	s.add("2");
	for (Object o : s) {
		System.out.println(o);
	}
}

因為原始類型沒有限制。但是,這很容易破壞集合的不變性。

簡而言之,通配符類型是安全的,而原始類型則不是。我們不能將任何元素放入Set<?>中。

3.Set<?>什么時候有用?

如果要使用泛型類型,但不知道或不在乎該參數的實際類型,則可以使用<?> 。它只能使用方法的參數。

例如:

public static void main(String[] args) {
	HashSet<Integer> s1 = new HashSet<Integer>(Arrays.asList(1,2,3));
	HashSet<Integer> s2 = new HashSet<Integer>(Arrays.asList(4,2,3));
 
	System.out.println(getUnion(s1, s2));
}
 
public static int getUnion(Set<?> s1, Set<?> s2){
	int count = s1.size();
	for(Object o : s2){
		if(!s1.contains(o)){
			count++;
		}
	}
	return count;
}

參考:

1.布洛赫,約書亞。有效的java。Addison -Wesley Professional,2008年。


“不積跬步,無以至千里”,希望未來的你能:有夢為馬 隨處可棲!加油,少年!

關注公眾號:「Java 知己」,每天更新 Java 知識哦,期待你的到來!

發送「面試」,領取 BATJ 面試資料、面試視頻攻略。
發送「Group」,與 10 萬程序員一起進步。
發送「玩轉算法」,領取《玩轉算法》系列視頻教程。
千萬不要發送「1024」,否則......


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM