我正在尝试编写一个方法,将任何List of List作为参数 - 无论嵌套列表的类型如何。
对于采用任何类型的单个列表的方法,通配符类型工作正常(请参阅示例1)。但是这个概念并未扩展到列表列表。从示例2中可以看出,该方法只接受List<List<?>>
类型的参数,但不接受特定类型的参数,例如List<List<Integer>>
。 Example3使用类型参数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) {}
答案 0 :(得分: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]
我希望这个解决方案符合您的期望。
答案 1 :(得分: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) {}