¿Por qué no puedes tener una “Lista <Lista >” en Java?

En Java, ¿por qué no funciona la siguiente línea de código?

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

Funciona si lo cambio a

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

Al principio, pensé que tal vez no puedas tener listas de una interfaz, pero puedo crear una List muy bien.

Ideas?

Los tipos generics son más pedantes.

List significa List o cualquier subtipo, pero significa solo List . Si desea un subtipo, debe tener < ? extends List> < ? extends List>

Sospecho que puedes usar

 List> myList = new ArrayList>(); 

La razón por la que no puede hacer esto es porque puede estar usando una referencia a una referencia y con un nivel adicional de indirección debe tener cuidado.

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

Con los generics puede tener dos niveles de indirección que le pueden dar problemas para que sean más pedantes para evitar estos problemas.

 // with two levels of indirection List alist = new ArrayList(); 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 

huellas dactilares

 Exception in thread "main" java.lang.ClassCastException: java.util.LinkedList cannot be cast to java.util.ArrayList 

Comencemos con esto:

  ArrayList> myList = new ArrayList>(); 

Esto está creando una ArrayList cuyos elementos son ArrayLists.

Ahora supongamos que podríamos asignar eso a

  List> myList2 = myList. 

Ahora, deberíamos poder hacer esto:

  myList2.add(new LinkedList()); 

Pero eso significa que hemos agregado una LinkedList a una lista cuyos elementos se supone que son ArrayLists. Ooops!

En realidad, la asignación de myList a myList2 no es legal … y eso asegura que no es posible agregar el tipo incorrecto de List al objeto ArrayList> . (No Peter, no es solo pedantería :-))

Solo la colección de nivel superior puede declararse como una clase de implementación, mientras que las anidadas deben seguir siendo interfaces hasta que realmente cree instancias:

 List> rootList = new ArrayList>(); 

y luego cuando crea un elemento para entrar, lo convierte en una implementación:

 List nodeList = new ArrayList(); rootList.add(nodeList); 

Compara el Type desde el lado izquierdo (statement) al Type desde el lado derecho (instanciación). En la izquierda, su tipo es List mientras que en la derecha, es ArrayList . Si se queja de la diferencia.

Actualice el lado derecho (instatiación) como Lista, es decir,

  List> myList = new ArrayList>(); 

Esto debería funcionar bien.

Sé que esta es una vieja pregunta, pero solo quería compartir mi idea.

En lugar de hacer una lista de listas, personalmente hago una lista de tipos [] ( List listArray = new ArrayList(); ), genero una lista separada de simplemente tipo ( List list = new ArrayList(); ), luego .add(list.toArray()) . De esta manera, es más claro y fácil de leer que la syntax de la Lista de listas, que es confusa.

Por ejemplo, en un proyecto reciente donde tenía un archivo de entrada donde cada línea con solo un “0” significaba una nueva línea en el original (era un algoritmo de encriptación):

 String[] input = getInputContents(inFile); List currentBuffer = new ArrayList(); List buffers = new ArrayList(); for(String line : input) { if(line.equals("0")) { buffers.add((String[])currentBuffer.toArray()); currentBuffer = new ArrayList(); } else { currentBuffer.add(line); } } 

la list> l1=new list>(); está permitido si la lista contiene una lista más dentro de la lista.

 public final class CPanelXMLBuilder extends PanelXMLBuilder { public CPanelXMLBuilder(AuthenticatedUser pAuthenticatedUser, Map pSessionMap, Map pRequestMap, String pPanelTemplate) throws Exception { super(pAuthenticatedUser, pSessionMap, pRequestMap, pPanelTemplate, null); } public Map buildXMLDocument(List> pDetailsList) { if (pDetailsList.size() == 1) { List 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; } }