2017-10-18 101 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] 

我希望這個解決方案滿足您的期望。