博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Set vs. Set<?>
阅读量:5782 次
发布时间:2019-06-18

本文共 2754 字,大约阅读时间需要 9 分钟。

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 Codepublic static void main(String[] args) {    HashSet
s1 = new HashSet
(Arrays.asList(1, 2, 3)); printSet(s1); HashSet
s2 = new HashSet
(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 Codepublic 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 CodeSet
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
s1 = new HashSet
(Arrays.asList(1,2,3)); HashSet
s2 = new HashSet
(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.

转载地址:http://ricyx.baihongyu.com/

你可能感兴趣的文章
iphone-common-codes-ccteam源代码 CCEncoding.m
查看>>
nginx中配置文件的讲解
查看>>
HTTP库Axios
查看>>
CentOS7下安装python-pip
查看>>
gen already exists but is not a source folder. Convert to a source folder or rename it 的解决办法...
查看>>
20个Linux服务器性能调优技巧
查看>>
填坑记:Uncaught RangeError: Maximum call stack size exceeded
查看>>
SpringCloud之消息总线(Spring Cloud Bus)(八)
查看>>
实时编辑
查看>>
KVO原理分析及使用进阶
查看>>
【348天】每日项目总结系列086(2018.01.19)
查看>>
【294天】我爱刷题系列053(2017.11.26)
查看>>
可替换元素和非可替换元素
查看>>
2016/08/25 The Secret Assumption of Agile
查看>>
(Portal 开发读书笔记)Portlet间交互-PortletSession
查看>>
搭建vsftpd服务器,使用匿名账户登入
查看>>
JAVA中循环删除list中元素的方法总结
查看>>
Java虚拟机管理的内存运行时数据区域解释
查看>>
人人都会深度学习之Tensorflow基础快速入门
查看>>
ChPlayer播放器的使用
查看>>