Преобразование вложенного списка в 2d-массив

Я пытаюсь преобразовать вложенный список в 2d-массив.

List<List<String>> list = new ArrayList<>();

list.add(Arrays.asList("a", "b", "c"));
list.add(Arrays.asList("dd"));
list.add(Arrays.asList("eee", "fff"));

Я хочу сделать это String[][]. Я пробовал следующее:

String[][] array = (String[][]) list.toArray();      // ClassCastException

String[][] array = list.toArray(new String[3][3]);   // ArrayStoreException

String[][] array = (String[][]) list.stream()        // ClassCastException
    .map(sublist -> (String[]) sublist.toArray()).toArray();

есть ли способ, который работает? Обратите внимание, что я не буду знать размер списка до выполнения, и он может быть неровным.

3 ответов


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

самым простым решением было бы создание двумерного массива и заполнение его результатами toArray из каждого вложенного списка.

String[][] array = new String[list.size()][];

int i = 0;
for (List<String> nestedList : list) {
    array[i++] = nestedList.toArray(new String[nestedList.size()]);
}

(вы можете сократить этот код, если вы используете Java 8 с потоками так же, как Алекс сделал)


вы могли бы сделать это:

String[][] array = list.stream()
    .map(l -> l.stream().toArray(String[]::new))
    .toArray(String[][]::new);

создает Stream<List<String>> из вашего списка списков, а затем из этого использует map чтобы заменить каждый из списков массивом строк, который приводит к Stream<String[]>, затем, наконец, называет toArray(С функцией генератора, вместо версии без параметров) на этом, чтобы произвести String[][].


немного короче, чем ответ Алекса:

final List<List<String>> list = ...;
final String[][] array = list.stream().map(List::toArray).toArray(String[][]::new);