29

在 Java 中,为什么以下代码行不起作用?

List<List<String>> myList = new ArrayList<ArrayList<String>>();

如果我将其更改为

List<ArrayList<String>> myList = new ArrayList<ArrayList<String>>();

起初,我想也许你不能有一个接口列表,但我可以创建一个List<Runnable>就好了。

想法?

4

6 回答 6

45

泛型类型更加迂腐。

List表示List或任何子类型,但<List>仅表示List. 如果你想要一个子类型,你需要有<? extends List>

我怀疑你可以使用

List<List<String>> myList = new ArrayList<List<String>>();

您不能这样做的原因是您可以使用对引用的引用,并且您必须小心额外的间接级别。

// with one level of indirection its simple.
ArrayList alist = new ArrayList();
List list = aList; // all good
list = new LinkedList(); // alist is still good.

使用泛型,您可以有两个间接级别,这会给您带来问题,因此它们会更加迂腐地避免这些问题。

// with two levels of indirection
List<ArrayList> alist = new ArrayList<ArrayList>();
List<List> list = (List) alist; // gives you a warning.
list.add(new LinkedList()); // adding a LinkedList into a list of ArrayList!!
System.out.println(alist.get(0)); // runtime error

印刷

Exception in thread "main" java.lang.ClassCastException: java.util.LinkedList
     cannot be cast to java.util.ArrayList
于 2012-10-12T14:58:01.597 回答
10

让我们从这个开始:

    ArrayList<ArrayList<String>> myList = new ArrayList<ArrayList<String>>();

这是创建一个 ArrayList,其元素是 ArrayList。

现在假设我们可以将其分配给

    List<List<String>> myList2 = myList.

现在,我们应该能够做到这一点:

    myList2.add(new LinkedList<String>());

但这意味着我们已将 LinkedList 添加到其元素应该是 ArrayLists 的列表中。哎呀!!!

实际上,myListto的分配myList2是不合法的……这确保了不可能向对象添加错误的List<String>类型ArrayList<ArrayList<String>>。(不,彼得,这不仅仅是迂腐:-​​))

于 2012-10-12T15:01:29.597 回答
3

只有顶级集合可以声明为实现类,而嵌套的集合必须保持接口,直到您实际创建实例:

List<List<String>> rootList = new ArrayList<List<String>>(); 

然后当您创建要进入的元素时,将其作为实现:

List<String> nodeList = new ArrayList<String>();
rootList.add(nodeList);
于 2012-10-12T15:02:42.147 回答
1

Type从左侧(声明)侧到Type右侧(实例化)侧进行比较。在左侧,您的类型List<String>在右侧,它是ArrayList<String>. 如果抱怨差异。

请将右侧(实例化)更新为列表,即

   List<List<String>> myList = new ArrayList<List<String>>();

这应该可以正常工作。

于 2012-10-12T15:02:01.480 回答
0

我知道这是一个老问题,但我只是想分享我的想法。

我个人并没有制作列表列表,而是制作了一个类型 [] ( List<Type[]> listArray = new ArrayList<Type[]>();) 的列表,我生成了一个仅包含类型 ( List<Type> list = new ArrayList<Type>();) 的单独列表,然后.add(list.toArray()). 这样,它比令人困惑的 List of Lists 语法更清晰、更容易阅读。

例如,在最近的一个项目中,我有一个输入文件,其中每一行只有一个“0”表示原始文件中的一个新行(它是一种加密算法):

String[] input = getInputContents(inFile);
List<String> currentBuffer = new ArrayList<String>();
List<String[]> buffers = new ArrayList<String[]>();

for(String line : input) {
    if(line.equals("0")) {
        buffers.add((String[])currentBuffer.toArray());
        currentBuffer = new ArrayList<String>();
    } else {
        currentBuffer.add(line);
    }
}
于 2016-02-10T14:26:00.290 回答
0

list<list<string>> l1=new list<list<string>>();如果列表中包含另一个列表,则允许使用。

public final class CPanelXMLBuilder extends PanelXMLBuilder {

    public CPanelXMLBuilder(AuthenticatedUser pAuthenticatedUser, Map<String, Object> pSessionMap, Map<String, Object> pRequestMap, String pPanelTemplate) throws Exception {
        super(pAuthenticatedUser, pSessionMap, pRequestMap, pPanelTemplate, null);
    }

    public Map<String, Object> buildXMLDocument(List<List<String>> pDetailsList) {

        if (pDetailsList.size() == 1) {
            List<String> pCustomerDetail = pDetailsList.get(0);
            xmlDocument.getRootElement().getChild("E_SHOW1").setText(pCustomerDetail.get(0));
            xmlDocument.getRootElement().getChild("E_SHOW2").setText(pCustomerDetail.get(1));
            xmlDocument.getRootElement().getChild("E_SHOW3").setText(pCustomerDetail.get(2));
            xmlDocument.getRootElement().getChild("E_SHOW4").setText(pCustomerDetail.get(3));
            xmlDocument.getRootElement().getChild("E_SHOW5").setText(pCustomerDetail.get(4));
            xmlDocument.getRootElement().getChild("ServerTimestamp").setText(pCustomerDetail.get(5).substring(0, 19));
        } else {
            xmlDocument.getRootElement().getChild("AlertType").setText("INFO");
            xmlDocument.getRootElement().getChild("Alert").setText("There is no matching record.");
        }

        requestMap.put(RequestMapKeys.XML_DOCUMENT, xmlDocument);

        return requestMap;
    }

}
于 2017-03-21T10:03:08.537 回答