Подтвердить что ты не робот

Преобразование ArrayList в 2D-массив, содержащий различные длины массивов

Итак, у меня есть:

ArrayList<ArrayList<String>> 

Что содержит x число ArrayLists, которые содержат другое y число строк. Чтобы продемонстрировать:

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

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

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

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

Большое вам спасибо.

4b9b3361

Ответ 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)

Ответ 2

Добро пожаловать в мир с 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);'

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

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

  1. Возьмите поток mainList 2D ArrayList. Этот поток немного похож на Vector, связанный с LinkedList, и у них был ребенок. И этот ребенок, позже в жизни, дозаправлялся на некоторых NZT-48. Я отвлекся; mainList.stream() возвращает поток элементов ArrayList<String>. Или даже в geekier говорят: mainList.stream() возвращает Stream<ArrayList<String>>, sorta.

  2. Вызовите функцию .map в этом потоке, которая вернет новый поток с содержимым, которое соответствует новому типу, заданному параметрами, переданными в map. Эта функция map будет скрывать каждый элемент нашего потока для нас. Он имеет встроенный оператор foreach. Чтобы это сделать; функция map принимает в качестве своего параметра лямбда-выражение. Выражение Lambda подобно простой встроенной однострочной функции. У этого есть два типа данных, которые можно использовать для Jiggy. Во-первых, это тип данных в потоке, на который он был вызван (mainList.stream()). Следующий тип - это тип данных, к которым он будет u → u.toArray(new String[0]), который находится в правой половине выражения лямбда: u → u.toArray(new String[0]). Здесь u - идентификатор, который вы выбираете так же, как при использовании инструкции foreach. Первая половина объявляет это так: u ->. И как и foreach, переменная u теперь будет каждым элементом в потоке, поскольку она итерации через поток. Таким образом, u относится к типу данных, что элементы исходного потока являются тем, что они являются ими. Правая половина выражения Lambda показывает, что делать с каждым элементом: u.toArray(new String[0]). При сохранении результатов в их законном месте в новом потоке. В этом случае мы преобразуем его в String[].. потому что в конце концов это 2D-массив String.. или, скорее, из этой точки кода, 1D-массив String[] (строковые массивы). Имейте в виду, что u в конечном счете является ArrayList. Обратите внимание, что вызов toArray из объекта ArrayList создаст новый массив типа, переданного в него. Здесь мы передаем new String[0]. Поэтому он создает новый массив типа String[] и имеет длину, равную длине ArrayList u. Затем он заполняет этот новый массив строк содержимым ArrayList и возвращает его. Что оставляет выражение Лямбды и обратно в map. Затем map собирает эти массивы строк и создает с ними новый поток, имеет связанный тип String[] а затем возвращает его. Поэтому в этом случае map возвращает Stream<String[]>. (Ну, на самом деле он возвращает Stream<Object[]>, который запутывает и нуждается в преобразовании, см. Ниже)

  3. Поэтому нам просто нужно вызвать toArray на этот новый поток массивов строк. Но вызов toArray в Stream<Object[]> немного отличается от вызова его в ArrayList<String>, как и раньше. Здесь мы должны использовать функцию, путающую вещь. Он захватывает тип из этого: String[][]::new. Эта new функция имеет тип String[][]. В принципе, поскольку функция вызывается toArray, она всегда будет []. В нашем случае, поскольку данные внутри были еще одним массивом, мы просто добавляем другое []. Я не знаю, почему NZT-48 не работал над этим. Я бы ожидал, что вызов по умолчанию toArray() будет достаточно, увидев, что его поток и все. Поток, который специально содержит Stream<String[]>. Кто-нибудь знает, почему map фактически возвращает Stream<Object[]> а не поток типа, возвращаемого выражением Lambda внутри?

  4. Теперь, когда мы получили toArray из нашего mainList потока, действующего правильно. Мы можем просто сбрасывать его в локальную переменную достаточно просто: String[][] stringArray = mainList.stream...

Преобразование 2D ArrayList из целых чисел в 2D-массив примитивных ints

Теперь, я знаю, что некоторые из вас идут туда. "Это не работает для ints!" Как и в моем случае. Однако он работает для " Ents ", см. Выше. Но если вам нужен 2D-примитивный массив int из 2D ArrayList 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 на ArrayList u; как и в предыдущем примере. Здесь мы вызываем toArray в Stream не в ArrayList. Поэтому по какой-то причине нам не нужно передавать ему "тип", я думаю, что он принимает мозговые стероиды. Поэтому мы можем воспользоваться опцией по умолчанию; где он получает удар этого NZT-48 и выясняет очевидное для нас это [время выполнения]. Я не уверен, почему он не мог просто сделать это в приведенном выше примере. О, это правильно.... ArrayLists не берут NZT-48, как Streams. Подождите... о чем я вообще говорю?

Annnyhoow, потому что потоки настолько умны. Как и Шелдон, нам нужен совершенно новый протокол, чтобы справиться с ними. По-видимому, продвинутый интеллект не всегда означает, что с ним можно справиться. Поэтому этот новый mapToInt необходим для создания нового Stream который мы можем использовать с его умным toArray. И i->i Lambda в mapToInt является простым распаковкой Integer для int, используя неявное авто-unboxing, которое позволяет int = Integer. Который теперь кажется глупым тривиальным делом, как будто разум имеет свои пределы. Во время моего приключения изучая все это: я на самом деле пытался использовать mapToInt(null) потому что я ожидал поведения по умолчанию. Не аргумент! (кашель Шелдон кашля) Тогда я сказал в своем лучшем Husker долины девушки акцент, "Afterall, это называется mapToInt, я предположил бы, что, вроде бы, 84% времени (42 х2) будет, как, прошли i->i, как, все, так что, omgawd! " Само собой разумеется, я чувствую себя немного... вроде.. этого парня. Не знаю, почему это так не работает!

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

PT

Ответ 3

Вы можете использовать метод 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() здесь.

Ответ 4

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

Ответ 5

Например:

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

Ответ 6

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

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

}