Как я могу конвертировать коллекциюобуглить [] [] в Java? - PullRequest
1 голос
/ 06 ноября 2019

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

У меня есть коллекцияchar-arrays Collection<char[]> как я могу преобразовать его в массив char-массивов char[][]?

Я пытался final char[][] kernelFeatures = (char[][]) features.toArray();

Однако я получаю сообщение об ошибке java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [[C ([Ljava.lang.Object; and [[C are in module java.base of loader 'bootstrap').

Ответы [ 2 ]

1 голос
/ 06 ноября 2019

Проблема

Причина, по которой вы не можете использовать Collection#toArray() и привести результат к char[][], заключается в том, что:

Возвращенный массив тип компонента среды выполнения равен Object.


Решения

Pre Java 11

Можно использовать Collection#toArray(T[]), который позволяет указать тип компонента массива.

Collection<char[]> collection = ...;
char[][] array = collection.toArray(new char[0][]);

Чтобы понять, почему вам не нужно указывать второе измерение, помните, что двумерные массивы в Java просто одно-размерные массивы, где каждый элемент является массивом. См. Эти вопросы и ответы для получения дополнительной информации:

Что касается использования 0 в качестве первого измерения, обратите внимание, что использование 0 не требуется;Вы можете использовать любую допустимую длину (например, collection.size()). Однако причина использования 0 заключается в том, что он предположительно более эффективен, по крайней мере при использовании ArrayList в HotSpot 8:

Я не уверен, является ли он более эффективным в других версиях, других реализациях JVM или для других Collectionреализации.

Java 11 +

Если вы используете Java 11+, существует альтернативное решение : Collection#toArray(IntFunction).

Collection<char[]> collection = ...;
char[][] array = collection.toArray(char[][]::new);

Что бы, как лямбда-выражение, выглядело бы следующим образом:

Collection<char[] collection = ...;
char[][] array = collection.toArray(i -> new char[i][]);

Ручное копирование

Оба метода #toArray в конечном итоге делают что-то похожее на:

Collection<char[]> collection = ...;

char[][] array = new char[collection.size()][];
int index = 0;
for (char[] element : collection) {
  array[index++] = element;
}

Хотя вам следует использовать один из методов #toArray, потому что это позволяет реализации Collection использовать любые возможные оптимизации. Например, класс ArrayList использует метод System#arraycopy.

0 голосов
/ 06 ноября 2019

Попробуйте:

  List<char[]> list = List.of(new char[] { '1', '2'
      }, new char[] { '3', '4'
      }, new char[] { '6', '7'
      });
      char[][] array = list.stream().toArray(char[][]::new);
      System.out.println(Arrays.deepToString(array));

или распечатать с помощью цикла for

    for (char[] c : array) {
        System.out.println(Arrays.toString(c));
    }
...