【问题标题】:Why can't you have a "List<List<String>>" in Java? [duplicate]为什么在 Java 中不能有一个“List<List<String>>”? [复制]
【发布时间】:2012-10-03 10:13:30
【问题描述】:

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

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

如果我改成它就可以了

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

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

想法?

【问题讨论】:

  • List&lt;List&lt;String&gt;&gt; myList = new ArrayList&lt;List&lt;String&gt;&gt;(); 怎么样?
  • @madth3 new ArrayList>() 仅当 List 是 java.awt.List 时才有效,而不是与 ArraList 相同的包>
  • List 是java.awt 中的一个类和java.util 包中的一个接口。所以你必须注意什么对你有好处。因为`ArrayList, it seems you are working with java.util, and java.util.List`可能会列在你的import中。 : 1°) new ArrayList&lt;ArrayList&lt;String&gt;&gt;() 很好,如果你想要 ArrayListArrayList 2°) new ArrayList&lt;List&lt;String&gt;&gt;() 将编译为 java.awt.List&lt;String&gt;

标签: java list arraylist


【解决方案1】:

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

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;
    }

}

【讨论】:

    【解决方案2】:

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

    我个人并没有制作列表列表,而是制作了一个类型 [] 的列表 (List&lt;Type[]&gt; listArray = new ArrayList&lt;Type[]&gt;();),我生成了一个单独的仅类型列表 (List&lt;Type&gt; list = new ArrayList&lt;Type&gt;();),然后是 .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);
        }
    }
    

    【讨论】:

      【解决方案3】:

      让我们从这个开始:

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

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

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

          List<List<String>> myList2 = myList.
      

      现在,我们应该可以这样做了:

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

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

      实际上,将myList 分配给myList2 是不合法的......这确保了不可能将错误类型的List&lt;String&gt; 添加到ArrayList&lt;ArrayList&lt;String&gt;&gt; 对象。 (不,彼得,这不是只是迂腐:-))

      【讨论】:

        【解决方案4】:

        泛型类型更加迂腐。

        List 表示List 或任何子类型,但&lt;List&gt; 仅表示List。如果你想要一个子类型,你需要有&lt;? extends List&gt;

        我怀疑你可以使用

        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
        

        【讨论】:

        • 是的,这似乎有效。你能解释一下为什么。谢谢
        • 您可以将LinkedList&lt;String&gt; 添加到List&lt;List&lt;String&gt;&gt;。您不能将LinkedList&lt;String&gt; 添加到ArrayList&lt;ArrayList&lt;String&gt;&gt;。因此,您不能创建引用ArrayList&lt;ArrayList&lt;String&gt;&gt;List&lt;List&lt;String&gt;&gt; 类型的变量,因为它们具有不同的行为。
        • 对于非泛型类型,您可以将ArrayList 分配给List,因为它会为您隐式转换。对于泛型类型,您不能将 &lt;ArrayList&gt; 强制转换为 &lt;List&gt;,因为它们是不同的类型。您可以将 &lt;ArrayList&gt; 转换为 &lt;? extends List&gt;,因为 ArrayList 扩展了 List。
        • java.util.List 是一个接口(java.awt.List 一个类),无法实例化。 ArrayList 是一个实现 java.util.List 的具体实例,建议用字段中的接口替换它,就像您在第一个示例中所做的那样
        • 出现问题是因为可以更改列表,添加不合格类的对象。如果您不更改列表,那么问题就会消失。有没有办法声明你不会更改列表?
        【解决方案5】:

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

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

        然后当你创建一个要进入的元素时,你把它变成一个实现:

        List<String> nodeList = new ArrayList<String>();
        rootList.add(nodeList);
        

        【讨论】:

        • "...嵌套的必须保持接口,直到您实际创建实例" 这不是真的。 List> x 是一个有效的声明,然后 x = new ArrayList>();确实有效。
        【解决方案6】:

        它比较左侧(声明)侧的Type 和右侧(实例化)侧的Type。在左侧,您的类型是 List&lt;String&gt;,而在右侧,它是 ArrayList&lt;String&gt;。如果抱怨差异。

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

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

        这应该可以正常工作。

        【讨论】:

          猜你喜欢
          • 2014-04-04
          • 2014-01-09
          • 1970-01-01
          • 2014-07-22
          • 2017-05-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多