关于java:嵌套列表中的泛型类型和通配符

Generic types and wildcards in nested lists

我正在尝试编写一个方法,它将列表的任何列表作为参数,而不管嵌套列表的类型如何。对于采用任何类型的单个列表的方法,通配符类型工作正常(请参见示例1)。但这个概念并没有扩展到列表列表中。如示例2中所示,该方法只接受List>类型的参数,而不接受List>等特定类型的参数。示例3使用类型参数T,并接受List>,但不再接受List>。为什么是这样?我如何编写一个同时接受List>List>的方法?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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>的亚型,即使ListList的亚型,也与List不是List的亚型相似,即使StringObject的亚型。基本上,当类型不是由通配符直接参数化时,类型参数必须完全匹配——ListList不完全匹配。(内部有一个通配符,但它是具体类型List的一部分,而不是顶层的通配符。)

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

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

这对我很有用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
[1, 2, 3, 4, 5]
[a, a, 2, 4, 5]

我希望这个解决方案符合您的期望。