You may know that an unbounded wildcard Set<?> can hold elements of any type, and a raw type Set can also hold elements of any type. What is the difference between them?

Two facts about Set<?>

There are two facts about Set<?>:
Item 1: Since the question mark ? stands for any type. Set<?> is capable of holding any type of elements. 
Item 2: Because we don't know the type of ?, we can't put any element into Set<?>

So a Set<?> can hold any type of element(Item 1), but we can't put any element into it(Item 2). Do the two statements conflict to each other? Of course they are not. This can be clearly illustrated by the following two examples:

Item 1 means the following situation:

//Legal Code
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);
}
}

Since Set<?> can hold any type of elements, we simply use Object in the loop.

Item 2 means the following situation which is illegal:

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

Because we don't know the type of <?> exactly, we can not add any thing to it other than null. For the same reason, we can not initialize a set with Set<?>. The following is illegal:

//Illegal Code
Set<?> set = new HashSet<?>();

Set vs. Set<?>

What's the difference between raw type Set and unbounded wildcard Set<?>?

This method declaration is fine:

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

because raw type has no restrictions. However, this will easily corrupt the invariant of collection.

In brief, wildcard type is safe and the raw type is not. We can not put any element into a Set<?>.

When Set<?> is useful?

When you want to use a generic type, but you don't know or care what the actual type the parameter is, you can use <?>[1]. It can only be used as parameters for a method.

For example:

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;
}

Reference:

1. Bloch, Joshua. Effective java. Addison-Wesley Professional, 2008.

 
 
 

Category >> Collections >> Generics >> Versus

http://www.programcreek.com/2013/12/raw-type-set-vs-unbounded-wildcard-set/

随机推荐

  1. 14.9.2 Specifying the Row Format for a Table 指定 表的行格式

    14.9.2 Specifying the Row Format for a Table 指定 表的行格式 mysql> SHOW TABLE STATUS\G; *************** ...

  2. python与其它语言进行比較

    近期python语言貌似比較火, 今天闲来无事,简单的看了下,算是个入门吧.一门语言之所以值得这么多人去学,必然有它的独到之处,以下我们就用python和其它语言做个比較. Pythond VS C# ...

  3. Jetty:配置JSP支持

    选择JSP实现 从Jetty-9.2開始,使用Apache Jasper作为默认JSP容器实现.在前面的版本号中使用的是Glassfish Jasper,在后面的版本号中也能够继续使用它. Jetty ...

  4. hdu1569find the safest road(floyd变形求最大安全值)

    find the safest road Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  5. RSA加密前言

    RSA:非对称加密,近期因为工作需要需要实现了一个RSA加密方案.查阅文档无数,主要是通过看他们代码及其引用他人的代码基本实现了跨平台的RSA方案.现在唯一的缺陷是加解密花费的时间太多,下周会把加解密 ...

  6. 两个Hacker,专门Patch TObject

    http://hallvards.blogspot.fr/2006/03/hack-8-explicit-vmt-calls.html http://www.deltics.co.nz/blog/po ...

  7. QT 4.2.2的安装(安装完还要再编译,注意设置Windows Path)

    (安装篇)前奏: 提到C++的GUI Framework估计大多数人都会想到MFC.VCL,因为在十年前的COM时代,这两个大家伙几乎垄断了整个C++ windows平台上应用程序的开发市场, 但是最 ...

  8.   PS2: 这篇文章中的图片绘图工具使用的是Dia (sudo apt-get install dia)。据说yEd也很不错。

    SBCL编译过程 - O.Nixie的专栏 - 博客频道 - CSDN.NET PS2: 这篇文章中的图片绘图工具使用的是Dia (sudo apt-get install dia).据说yEd也很不 ...

  9. cronjob不跑得原因

    能是环境的不同,能够在cronjob中加个env > /tmp/env.output查看 应用要同一时候输出标准错误合标准输出到一个文件能够&> /tmp/t

  10. ZOJ 1171 Sorting the Photos

    1. 题目描述 给你一叠照片,有的正面朝上,有的反面朝上,朝上的用字母U,朝下的用字母D 可以从一个位置开始到最顶端,把这一叠拿出来,反转,然后再放回那一叠照片上面. 试求出最少的翻转次数,使所有的照 ...