Как преобразовать список списков в двумерный массив в Java

#java #multidimensional-array

#java #многомерный массив

Вопрос:

Я придумал решение ниже, не уверен, можно ли удалить предупреждения типа:safety с помощью чего-то другого.

 BiFunction<List<List<T>>, Class<T>,T[][]> toArray = (list,type) ->
{
    T a[][] = (T[][]) Array.newInstance(type,
            list.size(), list.get(0).size());
    IntStream.range(0, a.length)
    .forEach(i -> {
        a[i]=(T[]) list.get(i).toArray();
    });
    return a;
};
  

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

Комментарии:

1. List.toArray() без аргумента всегда будет возвращаться Object[] — вам нужно также создать надлежащие экземпляры для компонентов, а не только для большего массива. Откуда вы получаете свои предупреждения?

2. извините, но я не понимаю, что именно вы хотите сделать? преобразовать List<List<T>> в T[][]

3. Я получаю предупреждения при первом назначении, также я хотел бы сказать, что мне пришлось переписать метод, когда я тестировал это на целочисленной матрице, поэтому теперь я использую ниже BiFunction<List<List<T>>, Class<T>,T[][]> toArray = (list,type) -> { T a[][] = (T[][]) Array.newInstance(list.get(0).get(0).getClass(), list.size(), list.get(0).size()); IntStream.range(0, list.size()) .forEach(i -> { IntStream.range(0, list.get(0).size()) .forEach(j -> { a[i][j]=list.get(i).get(j); }); }); return a; };

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

Ответ №1:

У меня есть два предложения, в обоих: преобразовать из списка в список, повторяя список списка и добавляя каждый элемент как T[] в новый список.

Используйте Array.newInstance только для создания вспомогательных объектов и добавления аннотации @SuppressWarnings

     @SuppressWarnings("unchecked")
    public static <T> T[][] toArray(List<List<T>> list, Class<T> type) {

    T aux[] = (T[]) Array.newInstance(type, 0);
    T auxBi[][] = (T[][]) Array.newInstance(type, 0, 0);

    List<T[]> newList = new ArrayList<>();
    list.forEach(e -> newList.add(e.toArray(aux)));

    T[][] newBi = newList.toArray(auxBi);

    return newBi;
}
  

или

добавьте вспомогательные символы в качестве параметров вместо типа

 public static <T> T[][] toArray(List<List<T>> list, T aux[], T auxBi[][]) {

    List<T[]> newList = new ArrayList<>();
    list.forEach(e -> newList.add(e.toArray(aux)));

    T[][] newBi = newList.toArray(auxBi);

    return newBi;

}
  

Комментарии:

1. Ценю этот ответ, это дало мне представление о том, чего я хотел достичь.

2. Решение выше с использованием конвейера потока public BiFunction<List<List<T>>,Class<T>, T[][]> toArr = (list,type)-> list.stream().map(row -> row.toArray((T[]) Array.newInstance(type, 0))).collect(Collectors.toList()).toArray((T[][]) Array.newInstance(type, 0, 0));