美文网首页
Java通配符——Set和Set区别

Java通配符——Set和Set区别

作者: 雁阵惊寒_zhn | 来源:发表于2020-09-25 15:00 被阅读0次

    写在前面

    JDK5引入了新特性——Java泛型(generics),泛型提供了编译时类型安全检测机制,在程序编译期间可以检查类型安全,实现参数类型的“任意化”。而在没有泛型的情况下,是通过对类型Object的引用来实现参数的“任意化”,这种方法需要显示的强制类型转换,但是强制类型转换错误只有在运行时才会出现异常。

    翻译一篇关于比照Set和Set<?>区别的英文文章,原文链接Set vs. Set<?>

    翻译原文如下

    1. 关于Set<?>的两个事实:

    第1条:由于通配符?代表的是任意类型,所以Set<?>可以包含任意类型的元素。
    第2条:因为不知道?类型,因此不可以放入任意元素。
    根据第1条Set<?>可以保存任何类型的元素,可是根据第2条又不能放入任何元素。但是两者却并不发生冲突,通过下面两个例子可以清晰阐述。

    第1条意味着下面情形:

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

    Set<?>可以包含任意类型的元素,我们在循环中对Object对象进行操作。

    第2条意味着下面的情形是不合法的:

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

    <?>的类型不能明确知道,因此不可以放入除了null以外的任何元素。相同的原因,不可以用Set<?>初始化一个set。下面的代码片段是非法的:

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

    那么Set与Set<?>之间的不同是什么呢?
    下面定义的方法可以很清楚看出:

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

    因为Set没有指定类型,对存入的元素没有任何的限制。这就很容易破坏集合的一致性,也就是集合中的元素类型可能不同。
    简单而言,通配符?类型是更加安全的,而原生类型是不安全的。我们不可以把任何元素放入到Set<?>中。

    1. 什么时候使用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;
    }
    

    相关文章

      网友评论

          本文标题:Java通配符——Set和Set区别

          本文链接:https://www.haomeiwen.com/subject/fzdayktx.html