studio son qué objeto metodos matrices manejo instanciar genericos generico genericas datos crear con comparar como clases arreglos java generics syntax types

son - metodos genericos java



Sintaxis de Java Generics para matrices (6)

Después de ejecutar algunas pruebas adicionales, creo que tengo mi respuesta.

List <ArrayList> [] sí especifica una matriz donde cada elemento es una lista de objetos ArrayList.

Al compilar el código como se muestra a continuación, se reveló por qué mi primera prueba me permitió usar una matriz donde cada elemento es una Lista de cualquier cosa. El uso de los tipos de devolución de Lista [] y Lista en los métodos que pueblan las matrices no proporcionó al compilador suficiente información para prohibir las asignaciones. Pero el compilador emitió advertencias sobre la ambigüedad.

Desde el punto de vista del compilador, un método que devuelve una Lista [] puede devolver una Lista <Lista de Arreglos> (que satisface la declaración) o puede que no. De manera similar, un método que devuelve una Lista puede devolver o no una ArrayList.

Aquí estaba la salida del compilador:

javac Generics2.java -Xlint: desmarcado

Generics2.java:12: warning: [unchecked] unchecked conversion found : java.util.List[] required: java.util.List<java.util.ArrayList>[] someListArray = getArrayWhereEachElementIsALinkedListObject(); ^ Generics2.java:16: warning: [unchecked] unchecked conversion found : java.util.List[] required: java.util.List<java.util.ArrayList>[] someListArray= getArrayWhereEachElementIsAListOfLinkedListObjects();

Aquí están mis pruebas.

import java.util.ArrayList; import java.util.List; import java.util.LinkedList; public class Generics2 { public static void main(String[] args) { List<ArrayList>[] someListArray; someListArray = getArrayWhereEachElementIsALinkedListObject(); // Why does this satisfy the declaration? //someListArray[0] => LinkedList object holding Strings someListArray= getArrayWhereEachElementIsAListOfLinkedListObjects(); //someListArray[0] => LinkedList object holding LinkedList objects } public static List[] getArrayWhereEachElementIsALinkedListObject() { List[] arrayOfLists = new LinkedList[2]; arrayOfLists[0] = getStringLinkedListAsList(); arrayOfLists[1] = getIntegerLinkedListAsList(); return arrayOfLists; } public static List[] getArrayWhereEachElementIsAListOfLinkedListObjects() { List list1 = new LinkedList(); list1.add(new LinkedList()); List list2 = new LinkedList(); list2.add(new LinkedList()); List[] arrayOfListsOfLinkedLists = new LinkedList[2]; arrayOfListsOfLinkedLists[0] = list1; arrayOfListsOfLinkedLists[1] = list2; return arrayOfListsOfLinkedLists; } public static List getStringLinkedListAsList() { List stringList= new LinkedList(); stringList.add("one"); stringList.add("two"); return stringList; } public static List getIntegerLinkedListAsList() { List intList= new LinkedList(); intList.add(new Integer(1)); intList.add(new Integer(2)); return intList; } }

¿Qué estructura de datos especifica la siguiente declaración?

List<ArrayList>[] myArray;

Creo que debería declarar una matriz donde cada elemento es una List (por ejemplo, una LinkedList o una LinkedList ArrayList ) y requiere que cada List contenga objetos ArrayList .

Mi razonamiento

List<String> someList; // A List of String objects List<ArrayList> someList; // A List of ArrayList objects List<ArrayList>[] someListArray; // An array of List of ArrayList objects

Después de ejecutar algunas pruebas, determiné que acepta una matriz donde cada elemento es un objeto LinkedList y no especifica qué contienen los objetos LinkedList.

Entonces List<ArrayList> especifica qué debe contener la List , pero List<ArrayList>[] especifica cómo se debe implementar la List .

¿Me estoy perdiendo de algo?

Aquí están mis pruebas.

import java.util.ArrayList; import java.util.List; import java.util.LinkedList; public class Generics1 { public static void main(String[] args) { List<ArrayList>[] someListArray; someListArray = getArrayWhereEachElementIsAnArrayListObject(); // Why does this satisfy the declaration? //someListArray[0] => ArrayList object holding Strings someListArray= getArrayWhereEachElementIsAListOfArrayListObjects(); //someListArray[0] => ArrayList object holding ArrayList objects } public static List[] getArrayWhereEachElementIsAnArrayListObject() { List[] arrayOfLists = new ArrayList[2]; arrayOfLists[0] = getStringList(); arrayOfLists[1] = getIntegerList(); return arrayOfLists; } public static List[] getArrayWhereEachElementIsAListOfArrayListObjects() { List list1 = new ArrayList(); list1.add(getArrayList()); List list2 = new ArrayList(); list2.add(getArrayList()); List[] arrayOfListsOfArrayLists = new ArrayList[2]; arrayOfListsOfArrayLists[0] = list1; arrayOfListsOfArrayLists[1] = list2; return arrayOfListsOfArrayLists; } public static List getStringList() { List stringList= new ArrayList(); stringList.add("one"); stringList.add("two"); return stringList; } public static List getIntegerList() { List intList= new ArrayList(); intList.add(new Integer(1)); intList.add(new Integer(2)); return intList; } public static ArrayList getArrayList() { ArrayList arrayList = new ArrayList() ; return arrayList; } }


El Sr. Josh Bloch dice:

"Prefiere listas a matriz porque las matrices son covariantes y los genéricos son invariables"

Quizás puedas hacer:

List<List<ArrayList>> someListArray;

Esto puede dar un golpe de rendimiento (ni siquiera es obvio que lo apueste), pero obtendrá un mejor tipo de seguridad en tiempo de compilación.

pero creo que la pregunta debería ser más sobre "por qué" necesitas esto?


La respuesta es que las matrices solo pueden contener tipos reificados. Y las clases genéricas no se reifican. Es decir, el "tipo" de tiempo de ejecución de List <ArrayList> es solo List. Los genéricos se borran en el tiempo de ejecución (google "wall of erasure" para obtener más información).

Así que esto:

List<ArrayList>[] myArray

realmente significa:

List[] myArray

No existe una forma segura de tipo para declarar lo que intentas declarar. En general, te recomiendo que uses una lista en lugar de una matriz en este caso. Algunas personas han llegado a sugerir que las matrices deberían tratarse como tipos obsoletos ahora que tenemos genéricos. No puedo decir que esté dispuesto a llegar tan lejos, pero debería considerar si una colección es una alternativa mejor cada vez que se siente atraído por una matriz.

El libro Java Generics and Collections de Naftalin and Wadler es una referencia excelente para las preguntas que pueda tener sobre los genéricos. O, por supuesto, las Preguntas frecuentes sobre genéricos es su referencia canónica en línea.


List es una lista capaz de contener objetos ArrayList List [] es una matriz de tales listas

Entonces, lo que dijiste es que An Array of (Lista del objeto ArrayList) es CORRECTO.

¿Puedes compartir cuáles fueron tus pruebas? Mis propias pruebas son diferentes

import java.util.*; public class TestList { public static void main(String ... args) { class MySpecialLinkedList extends LinkedList<ArrayList<Integer>> { MySpecialLinkedList() { } public void foo() { } public Object clone() { return super.clone(); } } List<ArrayList<Integer>> [] someListArray = new MySpecialLinkedList[10]; for (int i = 0; i < 10; ++i) { someListArray[i] = new LinkedList<ArrayList<Integer>>(); for (int j = 0; j < 20; ++j) { someListArray[i].add(new ArrayList<Integer>()); for (int k = 0; k < 30; ++k) { someListArray[i].get(j).add(j); } } } } }


Tienes razón al decir:

Después de ejecutar algunas pruebas, determiné que la declaración significa una matriz donde cada elemento es un objeto ArrayList.

Ejecutando este código

List<ArrayList>[] myArray = new ArrayList[2]; myArray[0] = new ArrayList<String>(); myArray[0].add("test 1"); myArray[1] = new ArrayList<String>(); myArray[1].add("test 2"); print myArray;

Produce este resultado:

{["test 1"], ["test 2"]}

Me parece que no hay ninguna razón para no hacer esto en su lugar:

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


List<ArrayList>[] someListArray;

te da una:

array of ( List of ArrayList )

Pero debido a las limitaciones en los genéricos de Java (error 6229728 ), solo puedes crear:

array of List

y echarlo:

List<ArrayList>[] someListArray = (List<ArrayList>[]) new List[5];