2017-10-18 112 views
0

我试图编写一个方法,它将任何列表List作为参数 - 不管嵌套列表的类型如何。
对于采用任何类型的单个列表的方法,通配符类型可以正常工作(请参阅example1)。但是这个概念并没有扩展到列表清单。如在示例2中可以看到的那样,该方法仅接受类型为List<List<?>>的参数,但不是特定类型的参数,例如List<List<Integer>>。示例3使用类型参数T并接受List<List<Integer>>,但不再接受List<List<?>>。为什么是这样,我怎么能写一个方法,接受List<List<?>>List<List<Integer>>嵌套列表中的通用类型和通配符

public void test() 
{ 
    List<Integer> list1; 
    List<?> list2; 

    example1(list1); // Valid 
    example1(list2); // Valid 

    List<List<Integer>> listOfLists1; 
    List<List<?>> listOfLists2; 

    example2(listOfLists1); // Error 
    example2(listOfLists2); // Valid 

    example3(listOfLists1); // Valid 
    example3(listOfLists2); // Error 
} 

public void example1(List<?> listOfLists) {} 

public void example2(List<List<?>> listOfLists) {} 

public <T> void example3(List<List<T>> listOfLists) {} 
+3

[这个问题](https://stackoverflow.com/questions/12861726/why-cant-you-have-a-listliststring-in-java)略微越过这里的问题。长话短说,你只需要使用'List <?扩展列表>'为'example2'和同样'List <? 'example3'扩展列表>。泛型可能非常挑剔。 – Obicere

回答

1

example2不起作用,因为List<List<Integer>>不是List<List<?>>即使List<Integer>List<?>一个亚型,类似于List<String>怎么不是List<Object>即使String亚型是Object子类型的子类型。基本上,当类型不是直接由通配符参数化时,类型参数必须完全匹配 - List<Integer>List<?>不完全匹配。 (这里有一个通配符,但它是具体类型List<?>的一部分,不是顶级通配符。)

为了能够采用不同的类型参数,它需要一个通配符在顶层:

public void example4(List<? extends List<?>> listOfLists) {} 
1

这对我的作品:

List<List<Integer>> listOfLists1; 
List<List<?>> listOfLists2; 

public TestKlasse() { 
    init(); 
} 

public void init(){ 
    listOfLists1 = new ArrayList(); 
    listOfLists2 = new ArrayList(); 
    listOfLists1.add(Arrays.asList(1,2,3,4,5)); 
    listOfLists2.add(Arrays.asList("a","a",2,4,"5")); 
    test((Collection)listOfLists1); 
    test((Collection)listOfLists2); 
} 

private void test(Collection<Collection<?>> list){ 
    list.forEach(e -> { 
     System.out.println(e.toString()); 
    }); 
} 

结果:

[1, 2, 3, 4, 5] 
[a, a, 2, 4, 5] 

我希望这个解决方案满足您的期望。