zoukankan      html  css  js  c++  java
  • Set vs. Set<?>(转)

    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/

  • 相关阅读:
    软件测试中桩模块与驱动模块的概念与区别(转载),打桩
    DataFactory使用和注意,排列组合
    SCWS中文分词,功能函数实例应用
    按指定长度截取中英文混合字符串
    CSS截取中英文混合字符串长度
    使DIV相对窗口大小左右拖动始终水平居中
    浮动5-常用列表显示(案例)
    多选项卡切换原理
    使当前对象相对于上层DIV 水平、垂直居中定位
    使图片相对于上层DIV始终水平、垂直都居中
  • 原文地址:https://www.cnblogs.com/softidea/p/4376646.html
Copyright © 2011-2022 走看看