Конвертировать ArrayList в 2D массив, содержащий переменные длины массивов

Так что я:

<code>ArrayList<ArrayList<String>> 
</code>

Который содержит x число ArrayLists, которые содержат еще y количество строк .. Для демонстрации:

<code>Index 0:
  String 1
  String 2
  String 3
Index 1:
  String 4
Index 2:
Index 3:
  String 5
  String 6
</code>

Где индекс относится к индексу массива, содержащему строку.

Как я могу преобразовать это в 2D массив, который выглядит так:

<code>{{String1, String2, String3},{String4}, {}, {String5, String6}}
</code>

Огромное спасибо.

Ответы на вопрос(6)

Добро пожаловать в мир с Java 8!

Мне потребовалась целая ночь без сна, чтобы понять, что нужно для написания этой чертовой строки кода. Я уверен, что это уже где-то там, но я не смог его найти. Итак, я делюсь своими часами исследований и получаю удовольствие. Woot!

Предполагая, что:

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

(Или, скорее, в Java 8:

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

)

Тогда все, что вам нужно, это:

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

Бам! Одна линия.

Я не уверен, насколько это быстро по сравнению с другими вариантами. Но вот как это работает:

Take a stream of the mainList 2D ArrayList. This stream is a bit like a Vector hooked up with a LinkedList and they had a kid. And that kid, later in life, dosed up on some NZT-48. I digress; mainList.stream() is returning a stream of ArrayList<String> elements. Or in even geekier speak: mainList.stream() returns a Stream<ArrayList<String>>, sorta.

Call the .map function on that stream which will return a new stream with contents that match a new type specified by the parameters passed into map. This map function will covert each element in our stream for us. It has a built in foreach statement. In order to accomplish this; the map function takes a lambda expression as its parameter. A Lambda expression is like a simple inline one-line function. Which has two data types gettin' Jiggy wit it. First is the type of data in the stream upon which it was called (mainList.stream()). The next type is the type of data it will map it out to, which is in the right half of the lambda expression: u -> u.toArray(new String[0]). Here u is an identifier you choose just like when using a foreach statement. The first half declares this like so: u ->. And like a foreach, the variable u will now be each element in the stream as it iterates through the stream. Thus, u is of the data type that the elements of the original stream are because it is them. The right half of the Lambda expression shows what to do with each element: u.toArray(new String[0]). With the results being stored in their rightful place in a new stream. In this case we convert it to a String[].. because after all, this is a 2D array of String.. or rather from this point in the code, a 1D array of String[] (string arrays). Keep in mind that u is ultimately an ArrayList. Note, calling toArray from an ArrayList object will create a new array of the type passed into it. Here we pass in new String[0]. Therefore it creates a new array of type String[] and with length equal to the length of the ArrayList u. It then fills this new array of strings with the contents of the ArrayList and returns it. Which leaves the Lambda expression and back into map. Then, map collects these string arrays and creates a new stream with them, it has the associated type String[] and then returns it. Therefore, map returns a Stream<String[]>, in this case. (Well, actually it returns a Stream<Object[]>, which is confusing and needs conversion, see below)

Therefore we just need to call toArray on that new stream of arrays of strings. But calling toArray on a Stream<Object[]> is a bit different than calling it on an ArrayList<String>, as we did before. Here, we have to use a function reference confusing thing. It grabs the type from this: String[][]::new. That new function has type String[][]. Basically, since the function is called toArray it will always be an [] of some sort. In our case since the data inside was yet another array we just add on another []. I'm not sure why the NZT-48 wasn't working on this one. I would have expected a default call to toArray() would be enough, seeing that its a stream and all. A stream thats specifically Stream<String[]>. Anyone know why map actually returns a Stream<Object[]> and not a stream of the type returned by the Lambda expression inside?

Now that we got the toArray from our mainList stream acting properly. We can just dump it into a local variable easy enough: String[][] stringArray = mainList.stream...

Convert 2D ArrayList of Integers to 2D array of primitive ints

Теперь я знаю, что некоторые из вас там собираются. & quot; Это не работает для ints! & quot; Как и в моем случае. Однако это работает для & quot;Энты& quot; см. выше. Но, если вы хотите 2D примитивint массив из 2DArrayList изInteger (То есть.ArrayList<ArrayList<Integer>>). Ты должен измениться вокруг этого среднего [земного] картографирования. Имейте в виду, что ArrayLists не могут иметь примитивные типы. Поэтому вы не можете позвонитьtoArray наArrayList<Integer> и ожидать, чтобы получитьint[], Вам нужно будет наметить это ... снова.

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

Я попытался выделить его для удобства чтения. Но вы можете видеть здесь, что мы должны снова пройти тот же самый процесс картирования. На этот раз мы не можем просто позвонитьtoArray в ArrayListu; как в приведенном выше примере. Здесь мы звонимtoArray наStream неArrayList, Поэтому по какой-то причине нам не нужно передавать его «типом», я думаю, что он принимает стероиды мозга. Следовательно, мы можем выбрать опцию по умолчанию; где он берет удар этого NZT-48 и вычисляет очевидное для нас это [время выполнения]. Я не уверен, почему он не мог просто сделать это в вышеприведенном примере. О, это правильно .... ArrayLists не принимают NZT-48, как это делают Streams. Подожди ... о чем я вообще здесь говорю?

Annnyhoow, потому что потоки ооочень умные. подобноШелдоннам нужен совершенно новый протокол для их решения. Очевидно, что развитый интеллект не всегда означает, что с ним легко иметь дело. Поэтому этот новыйmapToInt необходимо сделать новыйStream который мы можем использовать его умнееtoArray, Иi->i Лямбда-выражение вmapToInt это простая распаковкаInteger вint, используя неявную автоматическую распаковку, которая позволяетint = Integer, Что сейчас кажется глупой тривиальной вещью, как будто разум имеет свои пределы. Во время моего приключения изучая все это: я на самом деле пытался использоватьmapToInt(null) потому что я ожидал поведения по умолчанию. Не аргумент !! (cough Шелдонcough) Тогда я говорю в моих силахпочаткоочиститель акцент девицы долины, "В конце концов, этоis называетсяmapToIntЯ бы предположил, что, например, 84% времени (42х2) будет, вроде бы, пройденоi->i всем, так, как, омгавд! & quot; Излишне говорить, что я чувствую себя немного ... как ...этот парень, Не знаю, почему это так не работает!

Ну, я красноглазый, наполовину бред и наполовину спящий. Я, вероятно, сделал несколько ошибок; пожалуйста, просмотрите их, чтобы я мог исправить их и сообщить мне, если есть еще лучший способ!

PT

 10 февр. 2018 г., 22:53
посколькуmap принимает Lambda (который, как известно, знает тип данных каждой стороны Lambda), он должен иметь возможность передавать информацию о типе данных вперед. Итак, несмотря на мои сумасшедшие разговоры, я все же очень хотел бы получить ответ на эти два вопроса, упомянутых выше: 1) Почемуmap на самом деле вернутьStream<Object[]>  как поведение по умолчанию, а не поток типа, возвращаемого лямбда-выражением внутри? --- 2) ПочемуmapToInt не использовать по умолчаниюi->i ?

Например:

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

Ты можешь использоватьtoArray() метод для преобразования ArrayList в массив. Поскольку у вас есть ArrayList в ArrayList, вам нужно будет выполнить итерацию по каждому элементу и применить этот метод.

Что-то вроде этого:-

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

Вы можете найти больше оtoArray() Вот.

Этот полный мини-программный код отвечает на этот вопрос довольно понятно. Просто вставьте и запустите его:

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

}
Решение Вопроса
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 твойArrayList<ArrayList<String>> (или любойList<List<String>>измените первую строку внутриfor цикл соответственно)

 22 окт. 2018 г., 11:29
как вы проверяете и как выглядит ваш вклад?
 21 окт. 2018 г., 12:10
не работает для меня. Конечный 2d массив имеет только один столбец для каждой строки.
 22 июн. 2015 г., 08:07
Что если у меня есть ArrayList & lt; String [] & gt; и хотите преобразовать его в 2D-массив?
 29 июн. 2015 г., 18:32
извините, я пропустил это, вы, возможно, уже поняли это ... Во всяком случае, это простоString[][] array2D = new String[arrayList.size()][]; for (int i = 0; i < array2D.length; i++) { String[] row = arrayList.get(i); array2D[i] = row; }
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();
          }

Вы можете использовать приведенный ниже фрагмент кода для преобразования Object [] в String []

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

Ваш ответ на вопрос