java multidimensional-array arraylist indexing varying

java - Convierta ArrayList en una matriz 2D que contiene longitudes variables de matrices



multidimensional-array indexing (6)

Así que tengo:

ArrayList<ArrayList<String>>

Que contiene un número x de ArrayLists que contienen otro número y de cadenas. Para demostrar:

Index 0: String 1 String 2 String 3 Index 1: String 4 Index 2: Index 3: String 5 String 6

Donde el índice se refiere al índice de la matriz que contiene una cadena.

¿Cómo puedo transformar esto en una matriz 2D que se parece a:

{{String1, String2, String3},{String4}, {}, {String5, String6}}

Muchas gracias.


¡Bienvenido a un mundo con Java 8!

Solo me tomó toda la noche sin dormir para aprender lo que se necesitaba para escribir esta maldita línea de código. Estoy seguro de que ya está por ahí, pero no pude encontrarlo. Así que estoy compartiendo mis horas y horas de investigación, disfruten. Woot!

Asumiendo:

ArrayList<ArrayList<String>> mainList = new ArrayList<ArrayList<String>>(); // populate this list here

(O, mejor dicho, en Java 8:

ArrayList<ArrayList<String>> mainList = new ArrayList(); //Populate

)

Entonces todo lo que necesitas es:

String[][] stringArray = mainList.stream().map(u -> u.toArray(new String[0])).toArray(String[][]::new);

Bam! Una línea.

No estoy seguro de lo rápido que se compara con las otras opciones. Pero así es como funciona:

  1. Tome una corriente de la mainList ArrayList 2D. Este flujo es un poco como un Vector conectado con una Lista Lista y tuvieron un hijo. Y ese niño, más tarde en la vida, se rindió en algunos NZT-48 . Estoy divagando mainList.stream() está devolviendo una secuencia de elementos ArrayList<String> . O incluso en geekier speak: mainList.stream() devuelve un Stream<ArrayList<String>> , sorta.

  2. Llame a la función .map en esa secuencia que devolverá una nueva secuencia con contenidos que coincidan con un nuevo tipo especificado por los parámetros pasados ​​al map . Esta función de map convertirá cada elemento de nuestro flujo por nosotros. Tiene una declaración foreach integrada. Para lograr esto; la función de map toma una expresión lambda como su parámetro. Una expresión Lambda es como una simple función de una línea en línea. Que tiene dos tipos de datos obteniendo Jiggy wit it . Primero está el tipo de datos en el flujo sobre el cual fue llamado ( mainList.stream() ). El siguiente tipo es el tipo de datos al que se asignará, que se encuentra en la mitad derecha de la expresión lambda: u -> u.toArray(new String[0]) . Aquí, u es un identificador que elige igual que cuando usa una instrucción foreach . La primera mitad declara así: u -> . Y como un foreach , la variable u ahora será cada elemento en el flujo a medida que itera a través del flujo. Por lo tanto, u es del tipo de datos que los elementos del flujo original son porque son ellos. La mitad derecha de la expresión Lambda muestra qué hacer con cada elemento: u.toArray(new String[0]) . Con los resultados almacenados en el lugar que les corresponde en una nueva transmisión. En este caso, lo convertimos en una String[] ... porque después de todo, esta es una matriz 2D de String ... o más bien, desde este punto en el código, una matriz 1D de String[] (matrices de cadenas). Tenga en cuenta que u es, en última instancia, un ArrayList . Tenga en cuenta que llamar a toArray desde un objeto ArrayList creará una nueva matriz del tipo que se le pasa. Aquí pasamos en new String[0] . Por lo tanto, crea una nueva matriz de tipo String[] y con una longitud igual a la longitud de la ArrayList u . Luego llena este nuevo conjunto de cadenas con el contenido de ArrayList y lo devuelve. Lo que deja la expresión Lambda y vuelve al map . Luego, el map recopila estas matrices de cadenas y crea una nueva secuencia con ellas, tiene el tipo asociado String[] y luego lo devuelve. Por lo tanto, map devuelve un Stream<String[]> , en este caso. (Bueno, en realidad devuelve un Stream<Object[]> , que es confuso y necesita conversión, vea a continuación)

  3. Por lo tanto, solo necesitamos llamar a toArray en ese nuevo flujo de matrices de cadenas. Pero llamar a toArray en un Stream<Object[]> es un poco diferente a llamarlo en un ArrayList<String> , como hicimos antes. Aquí, tenemos que usar una función de referencia confusa cosa. Toma el tipo de esto: String[][]::new . Esa new función tiene tipo String[][] . Básicamente, dado que la función se llama toArray , siempre será un [] de algún tipo. En nuestro caso, ya que los datos internos eran otra matriz, simplemente agregamos en otra [] . No estoy seguro de por qué el NZT-48 no estaba funcionando en este caso. Habría esperado que una llamada predeterminada a toArray() fuera suficiente, ya que es una secuencia y todo. Una secuencia que es específicamente Stream<String[]> . ¿Alguien sabe por qué map devuelve un Stream<Object[]> y no un stream del tipo devuelto por la expresión Lambda que está dentro?

  4. Ahora que obtuvimos el toArray de nuestra transmisión mainList actuando correctamente. Simplemente podemos volcarlo en una variable local con bastante facilidad: String[][] stringArray = mainList.stream...

Convierta la Lista de Arrays 2D de Enteros en una matriz 2D de entradas primitivas

Ahora, sé que algunos de ustedes van por ahí. "¡Esto no funciona para los ints!" Como fue mi caso. Sin embargo, funciona para " Ents ", ver más arriba. Pero, si desea una matriz int primitiva 2D de una ArrayList 2D de Integer (es decir, ArrayList<ArrayList<Integer>> ). Tienes que cambiar alrededor de ese mapeo [tierra] medio. Tenga en cuenta que ArrayLists no puede tener tipos primitivos. Por lo tanto, no puede llamar a toArray en el ArrayList<Integer> y esperar obtener un int[] . Tendrá que mapearlo ... otra vez.

int[][] intArray = mainList.stream().map( u -> u.stream().mapToInt(i->i).toArray() ).toArray(int[][]::new);

Traté de espaciarlo para facilitar la lectura. Pero puede ver aquí que tenemos que pasar por el mismo proceso de mapeo completo nuevamente. Esta vez no podemos simplemente llamar a toArray en la ArrayList u ; como con el ejemplo anterior. Aquí estamos llamando a toArray on a Stream no a ArrayList . Entonces, por alguna razón, no tenemos que pasarle un "tipo", creo que está tomando esteroides cerebrales. Por lo tanto, podemos tomar la opción por defecto; donde recibe un golpe de ese NZT-48 y descubre lo obvio para nosotros esta vez. No estoy seguro de por qué no podía hacer eso en el ejemplo anterior. Oh, eso es correcto ... Las listas de arrays no toman NZT-48 como lo hacen los Streams. Espera ... ¿de qué estoy hablando aquí?

Annnyhoow, porque las corrientes son muy inteligentes. Al igual que Sheldon , necesitamos un protocolo completamente nuevo para tratar con ellos. Aparentemente, la inteligencia avanzada no siempre significa fácil de tratar. Por lo tanto, este nuevo mapToInt es necesario para crear un nuevo Stream que podamos usar su más inteligente toArray . Y la expresión i->i Lambda en mapToInt es un simple desempaquetado del Integer to int , utilizando el auto-descartado implícito que permite int = Integer . Lo que, ahora, parece una cosa tonta y trivial, como si la inteligencia tuviera sus límites. Durante mi aventura, aprendí todo esto: en realidad intenté usar mapToInt(null) porque esperaba un comportamiento predeterminado. No es un argumento !! ( tos Sheldon tos ) Entonces digo con mi mejor acento de Husker Valley: "Después de todo, se llama mapToInt , supongo que, como, el 84% del tiempo ( 42 x2) será, como, pasado i->i Yo por, como, todo el mundo, así que, omgawd! " No hace falta decir que me siento un poco ... como ... este tipo . ¡No sé por qué no funciona así!

Bueno, tengo ojos rojos y mitad delirante y medio dormido. Probablemente cometí algunos errores; Por favor, trótelos para que yo pueda arreglarlos y avisarme si hay una manera mejor.

PT


Este mini código de programa completo responde a esta pregunta de manera bastante autoexplicativa. Solo péguelo y ejecútelo

import java.util.ArrayList; import java.util.List; public class ListTo2Darray { public String[][] toArray(List<List<?>> list) { String[][] r = new String[list.size()][]; int i = 0; for (List<?> next : list) { r[i++] = next.toArray(new String[next.size()]); } return r; } public static void main(String[]arg){ String[][] sham; List<List<?>> mList = new ArrayList(); List<String> a= new ArrayList(); List<String> b= new ArrayList(); a.add("a"); a.add("a"); b.add("b"); b.add("b"); mList.add(a); mList.add(b); ListTo2Darray mt= new ListTo2Darray(); sham= mt.toArray(mList); System.out.println(sham[0][0]); System.out.println(sham[0][1]); System.out.println(sham[1][0]); System.out.println(sham[1][1]); } }


Por ejemplo:

public String[][] toArray(List<List<String>> list) { String[][] r = new String[list.size()][]; int i = 0; for (List<String> next : list) { r[i++] = next.toArray(new String[next.size()]); } return r; }


Puede usar el método toArray() para convertir un ArrayList en una matriz. Ya que tiene ArrayList dentro de ArrayList, necesitará iterar sobre cada elemento y aplicar este método.

Algo como esto:-

ArrayList<ArrayList<String>> mainList = new ArrayList<ArrayList<String>>(); // populate this list here //more code // convert to an array of ArrayLists ArrayList<String[]> tempList = new ArrayList<String[]>(); for (ArrayList<String> stringList : mainList){ tempList.add((String[])stringList.toArray()); } //Convert to array of arrays - 2D array String [][]list = (String[][])tempList.toArray();

Puede encontrar más información sobre toArray() here.


ArrayList<ArrayList<String>> list= new ArrayList<ArrayList<String>>(); ArrayList<String> a = new ArrayList<String>(); ArrayList<String> b = new ArrayList<String>(); a.add("Hello"); b.add("Hell"); list.add(a); list.add(b); Object[][] array = new Object[list.size()][]; Iterator<ArrayList<String>> iterator = list.iterator(); int i = 0; while(iterator.hasNext()){ array[i] = iterator.next().toArray(); }

Puede usar el siguiente fragmento de código para convertir el objeto [] en cadena []

String[] stringArray = Arrays.copyOf(objectArray, objectArray.length, String[].class);


String[][] array = new String[arrayList.size()][]; for (int i = 0; i < arrayList.size(); i++) { ArrayList<String> row = arrayList.get(i); array[i] = row.toArray(new String[row.size()]); }

donde arrayList es su ArrayList<ArrayList<String>> (o cualquier List<List<String>> , cambie la primera línea dentro del bucle for consecuencia)