嵌套列表中的泛型类型和通配符

时间:2017-10-18 16:41:14

标签: java list generics wildcard

我正在尝试编写一个方法,将任何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) {}

2 个答案:

答案 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>的子类型,即使StringObject的子类型。基本上,当类型未通过通配符直接参数化时,类型参数必须完全匹配 - List<Integer>List<?>不完全匹配。 (内部有一个通配符,但它是具体类型List<?>的一部分,而不是顶层的通配符。)

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

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