• 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」,否则......

  • 相关阅读:
    Excel的小游戏总结
    借助“URLScan”工具隐藏header头服务器信息
    WinCe设备连接Win10系统
    WinForm 通过HttpWebRequest实现大文件上传
    Sql 动态行转列 pivot
    C# 调用LAKALA接口获取静态二维码数据
    蜗牛星际黑群晖硬盘休眠的设置
    GIT Windows服务端搭建笔记
    C#通过socket判断FTP服务器是否通畅并判断用户名密码是否正确
    C#获取MAC地址
  • 原文地址:https://www.cnblogs.com/java-friend/p/11612711.html
Copyright © 2020-2023  润新知