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

本文共 2990 字,大约阅读时间需要 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://www.cnblogs.com/rollenholt/articles/4237790.html,如需转载请自行联系原作者

你可能感兴趣的文章
os模块大全详情
查看>>
【ros】Create a ROS package:package dependencies报错
查看>>
从内积的观点来看线性方程组
查看>>
kali linux 更新问题
查看>>
HDU1576 A/B【扩展欧几里得算法】
查看>>
廖雪峰javascript教程学习记录
查看>>
WebApi系列~目录
查看>>
限制CheckBoxList控件只能单选
查看>>
Java访问文件夹中文件的递归遍历代码Demo
查看>>
项目笔记:测试类的编写
查看>>
如何迅速分析出系统CPU的瓶颈在哪里?
查看>>
通过容器编排和服务网格来改进Java微服务的可测性
查看>>
re:Invent解读:没想到你是这样的AWS
查看>>
PyTips 0x02 - Python 中的函数式编程
查看>>
阿里云安全肖力:安全基础建设是企业数字化转型的基石 ...
查看>>
使用《Deep Image Prior》来做图像复原
查看>>
如何用纯 CSS 为母亲节创作一颗像素画风格的爱心
查看>>
Linux基础命令---rmdir
查看>>
优秀程序员共有的7种优秀编程习惯
查看>>
iOS sqlite3(数据库)
查看>>