2012-04-06 27 views
14

Así que tiene:Convert ArrayList en una matriz 2D que contiene diferentes longitudes de arrays

ArrayList<ArrayList<String>> 

que contiene un número x de ArrayLists que contienen otro y número 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 índice se refiere al índice de 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.

Respuesta

24
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 en consecuencia)

+1

¿Qué pasa si tengo ArrayList y quiero convertirlo en un 2D matriz? – shridatt

+3

lo siento, me olvidé de esto, puede que ya lo haya descubierto ... De todos modos, es simplemente 'Cadena [] [] array2D = new Cadena [arrayList.size()] []; for (int i = 0; i

5

Puede utilizar el método toArray() para convertir una ArrayList en una matriz. Como tiene ArrayList dentro de ArrayList, deberá 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.

1
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 utilizar el siguiente fragmento de código para convertir Object [] para String []

String[] stringArray = Arrays.copyOf(objectArray, objectArray.length, String[].class); 
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; 
} 
14

Bienvenido a un mundo con Java 8!

Solo me llevo 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!

Suponiendo:

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

(O, más bien, en Java 8:

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

)

Entonces todo lo que necesita es:

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

Bam! Una línea.

No estoy seguro de qué tan rápido es en comparación con las otras opciones. Pero esto es como funciona:

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

  2. Llame a la función .map en esa secuencia que devolverá una nueva secuencia con contenido que coincida con un nuevo tipo especificado por los parámetros pasados ​​a map. Esta función map encubrirá cada elemento en nuestra secuencia para nosotros. Tiene una declaración incorporada en foreach. Para lograr esto; la función map toma una expresión lambda como su parámetro. A Lambda expression es como una simple función en línea de una línea. Que tiene dos tipos de datos gettin' Jiggy wit it. Primero es el tipo de datos en la secuencia en la que se llamó (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 usted elige al igual que cuando usa una declaración foreach. La primera mitad lo declara así: u ->. Y al igual que foreach, la variable u ahora será cada elemento en la secuencia a medida que recorre la secuencia. Por lo tanto, u es del tipo de datos que los elementos de la secuencia original son porque es 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 String[] .. porque, después de todo, se trata de 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 al llamar al toArray desde un objeto ArrayList, se creará una nueva matriz del tipo que se le haya pasado. 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 ArrayList u. A continuación, rellena esta nueva matriz de cadenas con el contenido de ArrayList y la devuelve. Lo cual deja la expresión Lambda y vuelve al map. Luego, map recoge 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 Stream<String[]>, en este caso. (Bueno, en realidad devuelve un Stream<Object[]>, que es confuso y necesita conversión, ver más abajo)

  3. Por lo tanto, sólo tiene que llamar toArray en esa nueva corriente de matrices de cadenas. Pero llamar al toArray en un Stream<Object[]> es un poco diferente que llamarlo a un ArrayList<String>, como lo hicimos anteriormente. Aquí, tenemos que usar una cosa de confusión de referencia de función. Agarra el tipo de esto: String[][]::new. Esa función new tiene el tipo String[][]. Básicamente, dado que la función se llama para Array, siempre será un [] de algún tipo. En nuestro caso, dado que los datos en el interior eran otra matriz, simplemente agregamos otro []. No estoy seguro de por qué el NZT-48 no estaba trabajando en este. Hubiera 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 realmente devuelve Stream<Object[]> y no una secuencia del tipo devuelto por la expresión Lambda dentro?

  4. Ahora que tenemos el toArray de nuestra corriente mainList actuando correctamente.Sólo podemos volcar en una variable local bastante fácil: String[][] stringArray = mainList.stream...

Conversor 2D ArrayList de números enteros a la matriz 2D de enteros primitivos

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

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

He intentado espaciarlo para una mejor legibilidad. Pero puede ver aquí que tenemos que pasar por el mismo proceso de mapeo completo nuevamente. Esta vez no podemos simplemente llamar al toArray en ArrayList u; como en el ejemplo anterior. Aquí estamos llamando toArray en un Stream no un ArrayList. Entonces, por alguna razón, no tenemos que pasarle un "tipo", creo que es tomar esteroides cerebrales. Por lo tanto, podemos tomar la opción predeterminada; donde se necesita un golpe de ese NZT-48 y se da cuenta de lo obvio para nosotros este [tiempo de ejecución]. No estoy seguro de por qué no podría hacer eso en el ejemplo anterior. Oh, eso es correcto ... ArrayLists no toma NZT-48 como las Streams do. Espera ... ¿de qué estoy hablando aquí?

Annnyhoow, porque las transmisiones son taaaan inteligentes. Al igual que Sheldon, necesitamos un protocolo completamente nuevo para tratar con ellos. La inteligencia aparentemente avanzada no siempre significa fácil de tratar. Por lo tanto, este nuevo mapToInt es necesario para hacer un nuevo Stream que podemos usar su más inteligente toArray. Y la expresión i->i Lambda en mapToInt es un simple unboxing de Integer a int, utilizando el auto-unboxing implícito que permite int = Integer. Lo cual, ahora, parece una tontería trivial, como si la inteligencia tuviera sus límites. Durante mi aventura, aprendí todo esto: de hecho, traté de usar mapToInt(null) porque esperaba un comportamiento predeterminado. ¡No es una discusión! (tos Sheldon tos) entonces yo digo en mi mejor chica acento Husker valle, "Después de todo, es es llamados mapToInt, yo supongo que al igual que, el 84% de las veces (42 x2) Será, como, pasó i->i por, como, todos, así que como, omgawd! " Huelga decir que me siento un poco ... como .. this guy. ¡No sé por qué no funciona de esa manera!

Bueno, soy de ojos rojos, medio delirante y medio dormido. Probablemente cometí algunos errores; por favor trollos para que pueda arreglarlos y decirme si hay una manera aún mejor!

PT

+0

Dado que' map' toma un Lambda (que supuestamente conoce el tipo de datos de cada lado del Lambda), debe poder pasar esa información del tipo de datos hacia adelante. Entonces, a pesar de mis divagaciones locas, todavía me gustaría una respuesta a las dos preguntas mencionadas anteriormente: 1) ¿Por qué 'map' en realidad devuelve un' Stream 'como un comportamiento predeterminado y no una secuencia del tipo devuelto por el Lambda expresión dentro? --- 2) ¿Por qué 'mapToInt' no tiene un uso predeterminado de' i-> i'? –

0

Este mini código completo programa responde a esta pregunta en bastante pasta way.Just explica por sí mismo y ejecutarlo:

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

} 
Cuestiones relacionadas