嵌套列表中的通用类型和通配符
问题描述:
我试图编写一个方法,它将任何列表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) {}
答
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) {}
答
这对我的作品:
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]
我希望这个解决方案满足您的期望。
[这个问题](https://stackoverflow.com/questions/12861726/why-cant-you-have-a-listliststring-in-java)略微越过这里的问题。长话短说,你只需要使用'List >'为'example2'和同样'List >。泛型可能非常挑剔。 – Obicere