Convertir ArrayList en tableau 2D contenant différentes longueurs de tableaux

j'ai Donc:

ArrayList<ArrayList<String>> 

qui contient un nombre x D'ArrayLists qui contient un autre nombre y de chaînes.. Pour le démontrer:

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

Où l'indice renvoie à l'index de tableau contenant une chaîne de caractères.

Comment puis-je transformer ceci en un tableau 2D qui ressemble à:

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

Merci beaucoup.

16
demandé sur Stefan Dunn 2012-04-06 16:01:02

6 réponses

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

arrayList votre ArrayList<ArrayList<String>> (ou List<List<String>>, changez la première ligne à l'intérieur du for boucle en conséquence)

27
répondu michele b 2012-04-06 12:16:11

Bienvenue dans un monde avec Java 8!

il m'a fallu toute la nuit sans dormir pour apprendre ce qu'il fallait pour écrire cette foutue ligne de code. Je suis sûr qu'il est déjà quelque part, mais je ne l'ai pas trouvé. Donc je partage mes heures et mes heures de recherche, profites-en. Woot!

en Supposant que:

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

(ou, plutôt, en Java 8:

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

)

Ensuite, vous aurez besoin de:

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

Bam! Un ligne.

Je ne suis pas sûr de la vitesse à laquelle il est comparé aux autres options. Mais c'est la façon dont il fonctionne:

  1. Prendre un flux de l' mainList 2D ArrayList. Ce flux est un peu comme un Vecteur accroché avec un LinkedList et ils ont eu un enfant. Et cet enfant, plus tard dans la vie, a fait une overdose sur certains NZT-48. Je m'égare; mainList.stream() retourne un flux de ArrayList<String> éléments. Ou dans le même geekier parler: mainList.stream() retourne un Stream<ArrayList<String>>, sorta.

  2. appelez le .map fonction sur ce flux qui renvoie un nouveau flux dont le contenu correspond à un nouveau type spécifié par les paramètres passés dans map. Ce map fonction couvrira chaque élément de notre flux pour nous. Il a construit dans le foreach déclaration. Afin de le réaliser;map fonction prend une expression lambda comme paramètre. Lambda expression est comme une simple fonction en ligne d'une ligne. Qui dispose de deux types de données gettin' Jiggy wit it. Le premier est le type de données dans le flux sur lequel il a été appelé (mainList.stream()). Le type suivant est le type de données auquel il correspond, qui est dans la moitié droite de l'expression lambda:u -> u.toArray(new String[0]). Ici u est un identifiant que vous choisissez tout comme lors de l'utilisation d'un foreach déclaration. La première moitié déclare comme ceci: u ->. Et comme foreach la variable u va maintenant être de chaque élément dans le flux comme il itère dans le courant. Ainsi,u est du type de données que les éléments du flux d'origine parce qu'il . La moitié droite de l'expression Lambda montre comment faire avec chaque élément: u.toArray(new String[0]). Avec les résultats stockés dans leur place légitime dans un nouveau flux. Dans ce cas nous le convertissons en String[].. parce qu'après tout, c'est un tableau 2D de String.. ou plutôt à partir de ce point dans le code, un tableau 1D de String[] (tableaux de chaîne). Gardez à l'esprit que u est finalement ArrayList. Remarque, en appelant toArray d'un ArrayList objet de créer un nouveau tableau du type passé en elle. Ici nous passons en new String[0]. Par conséquent, il crée un nouveau tableau de type String[] et avec une longueur égale à la longueur de l'ArrayList u. Il remplit alors ce nouveau tableau de chaînes avec le contenu du ArrayList et le renvoie. Ce qui laisse l'expression Lambda et de nouveau dans map. Alors, map collecte ces tableaux de chaînes de caractères et en crée un nouveau flux avec eux, il a associé le type String[] et puis la retourne. Par conséquent, map retourne un Stream<String[]>, dans ce cas. (Bon, en fait il retourne un Stream<Object[]>, ce qui prête à confusion et nécessite une conversion, voir ci-dessous)

  3. Donc nous avons juste besoin d'appeler toArray sur ce nouveau flux de tableaux de cordes. Mais en l'appelant toArray sur un Stream<Object[]> c'est un peu différent que de l'appeler sur un ArrayList<String>, comme nous l'avons fait avant. Ici, nous devons utiliser une référence de fonction qui prête à confusion. Il attrape le type de ceci: String[][]::new. Que new la fonction a le type String[][]. En gros, puisque la fonction s'appelle toArray il sera toujours un [] d'une certaine sorte. Dans notre cas puisque les données à l'intérieur étaient encore un autre tableau nous ajoutons juste sur un autre []. Je ne sais pas pourquoi le NZT-48 ne marchait pas sur celui-ci. J'aurais attendu un appel par défaut à toArray() suffirait, vu que c'est un ruisseau et tout. Un ruisseau en particulier Stream<String[]>. Quelqu'un sait pourquoi map renvoie en fait un Stream<Object[]> et pas un ruisseau du type retourné par L'expression Lambda à l'intérieur?

  4. Maintenant que nous avons eu l' toArray à partir de notre mainList flux agissant correctement. Il nous suffit de le vider dans une variable locale assez facile: String[][] stringArray = mainList.stream...

Convertir 2D liste de tableaux d'Entiers de tableau 2D de la primitive ints

maintenant, je sais que certains d'entre vous y vont. "Cela ne fonctionne pas pour ints!"Comme cela a été mon cas. Il fonctionne cependant pour "-", voir ci-dessus. Mais, si vous voulez un primitif 2D int tableau à partir d'une 2D ArrayListInteger (ie. ArrayList<ArrayList<Integer>>). Vous devez changer autour de cette[terre] du milieu de la cartographie. Gardez à l'esprit que les ArrayLists ne peuvent pas avoir des types primitifs. Par conséquent, vous ne pouvez pas appeler toArray sur le ArrayList<Integer> et s'attendent à obtenir un int[]. Vous aurez besoin de la carte... encore.

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

j'ai essayé de l'espacer pour la lisibilité. Mais vous peut voir ici que nous devons passer par le même processus de cartographie à nouveau. Cette fois, nous ne pouvons pas simplement appeler toArray sur l'ArrayList u; comme avec l'exemple ci-dessus. Ici, nous appelons toArray sur un StreamArrayList. Donc, pour une raison quelconque, nous n'avons pas à lui passer un "type", je pense qu'il prend des stéroïdes cérébraux. Par conséquent, nous pouvons prendre l'option par défaut; où il prend un coup de ce NZT-48 et de comprendre l'évident pour nous ce [run]temps. Je ne sais pas pourquoi il ne pouvait pas juste faire que sur l'exemple ci-dessus. Oh, c'est vrai.... Les ArrayLists ne prennent pas le NZT-48 comme le font les Streams. Attendre... que suis-je parle même pas ici?

Annnyhoow, parce que les ruisseaux sont si intelligents. Comme Sheldon, nous avons besoin d'un tout nouveau protocole de traiter avec eux. Apparemment, l'intelligence avancée n'est pas toujours facile à gérer. Par conséquent, cette nouvelle mapToInt est nécessaire de faire un nouveau Stream que nous pouvons utiliser son plus intelligent toArray. Et le i->i Lambda expression dans mapToInt est une simple décompression du Integerint, en utilisant l'auto-unboxing implicite qui permet int = Integer. Ce qui, maintenant, semble être une chose stupide et insignifiante à faire, comme si l'intelligence avait ses limites. Pendant mon apprentissage d'aventure tout cela: j'ai effectivement essayé d'utiliser mapToInt(null) parce que je m'attendais à un comportement par défaut. Pas un argument!! (toux Sheldon toux), Alors je le dis dans mon meilleur Husker vallée de la fille accent, "après tout, il mapToInt, je suppose que, comme, 84% du temps ( 42x2), il sera, comme, passé i->i, comme, tout le monde, donc comme, omgawd!"Inutile de dire que je me sens un peu... comme.. ce mec. Je ne sais pas pourquoi ça ne marche pas comme ça!

Eh bien, je suis yeux rouges et à moitié délirant et à moitié endormi. J'ai probablement fait quelques erreurs, merci de troll si je peux les corriger et laissez-moi savoir si il est encore mieux chemin!

PT

20
répondu Pimp Trizkit 2018-02-10 21:48:12

Vous pouvez utiliser toArray() méthode pour convertir un ArrayList en un tableau. Puisque vous avez ArrayList dans ArrayList, vous devrez itérer sur chaque élément et appliquer cette méthode.

quelque Chose comme ceci:-

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();

vous pouvez en savoir plus sur toArray()ici.

5
répondu vaisakh 2012-04-06 12:15:57
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();
          }

vous pouvez utiliser l'extrait ci-dessous pour convertir L'objet[] en chaîne[]

String[] stringArray = Arrays.copyOf(objectArray, objectArray.length, String[].class);
1
répondu Chandra Sekhar 2012-04-06 12:15:17

Par exemple:

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;
}
1
répondu Eugene Retunsky 2012-04-06 12:37:32

ce mini-code de programme complet répond à cette question de manière assez explicite.Il suffit de coller et de l'exécuter:

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

}
0
répondu Harjit Singh 2016-06-27 07:16:36