#java #arrays #generics
#java #массивы #общие сведения
Вопрос:
public static <T> T[][] toTwoDim(T[] array)
Сигнатура функции, как указано выше..
Это универсальная типизированная функция, которая может использоваться независимо от типа данных, содержащихся в массиве.
как правило, она получает массив и возвращает 2-мерный массив, половина элементов которого находится в первой строке, а другая половина — во второй строке.
Я понятия не имею, как это реализовать, потому что я не смог создать универсальный типизированный 2-мерный массив внутри функции.
Кто-нибудь мне поможет?
Спасибо!
Комментарии:
1. Я думаю, точная процедура не очень важна для того, чтобы заботиться о ней. Основная проблема, с которой я столкнулся, заключается в том, как я мог создать соответствующее возвращаемое значение, иначе говоря, универсальный типизированный двумерный массив. Мы можем предположить более простое отображение, как я описал в исходном сообщении: функция разбивает массив на две части, каждая часть имеет свои половинные элементы, и одна часть хранится в первой «строке» двумерного массива, а другая часть — во второй «строке».
Ответ №1:
Я довольно долго играл с этим, и, насколько я понимаю, по причинам удаления типа, это невозможно.
Основываясь на других примерах создания массивов параметров универсального типа, кажется, что должно сработать что-то вроде следующего кода, но в конечном итоге это приводит к сбою только при возврате функции, где Object[][]
не может быть приведено к Integer[][]
. Ранее это завершилось бы неудачей, за исключением того, что IIRC, из которого исходное приведение (T[][])
, в основном удаляется во время компиляции и предотвращает предупреждение, поэтому оно не оказывает реального влияния.
@SuppressWarnings("unchecked")
public static <T> T[][] toTwoDim(T[] array){
int halflen = array.length / 2;
T[][] foo = (T[][]) new Object[2][];
foo[0] = (T[]) new Object[halflen];
foo[1] = (T[]) new Object[halflen];
for(int i = 0; i < halflen; i ){
foo[0][i] = array[i];
foo[1][i] = array[i halflen];
}
System.out.println(Arrays.asList(foo[0]));
System.out.println(Arrays.asList(foo[1]));
return foo;
}
public static void main(String[] a){
Integer[] bar = {1,2,3,4};
Integer[][] foo = toTwoDim(bar);
System.out.println(Arrays.asList(foo[0]));
}
Комментарии:
1. спасибо за ваше объяснение, может быть, я бы нашел другой подход к выполнению задачи.
Ответ №2:
Это должно быть возможно сделать.
Основной подход заключается в использовании java.lang.reflect.Array.newInstance(clazz, dimX, dimY)
для создания экземпляра массива.
-
Если вы хотите, чтобы базовый тип результирующего массива совпадал с базовым типом аргумента, то используйте отражение, чтобы получить базовый тип из
array.getClass()
. -
Если вы хотите, чтобы базовый тип результирующего массива был
<T>
, то вам нужно будет добавить дополнительный аргумент к,toTwoDim
тип которогоClass<T>
, и использовать его для передачи объекта класса для требуемого базового типа массива. (Удаление типа означает, чтоtoTwoDim
метод не может определить объект класса для<T>
во время выполнения. Передача объекта класса в качестве аргумента является стандартным обходным путем.)
Ответ №3:
Я нашел идеальное решение:
@SuppressWarnings("unchecked")
public static <T> T[][] toTwoDim(T[] array) {
Class<T> ctype = (Class<T>) array.getClass().getComponentType();
int halfLength = array.length / 2;
T[][] ret = (T[][]) Array.newInstance(ctype, 2, 1);
T[] r1 = (T[]) Array.newInstance(ctype, halfLength);
T[] r2 = (T[]) Array.newInstance(ctype, array.length - halfLength);
ret[0] = r1;
ret[1] = r2;
for (int i = 0; i < halfLength; i )
r1[i] = array[i];
for (int i = 0; i < array.length - halfLength; i ) {
r2[i] = array[i halfLength];
}
return ret;
}
public static void main(String[] a) {
Integer[] bar = { 1, 2, 3, 4, 5 };
Integer[][] dims = toTwoDim(bar);
for (Integer[] r : dims) {
for (Integer d : r) {
System.out.print(d " ");
}
System.out.println();
}
}
вывод:
1 2
3 4 5
общий тип функции ‘toTwoDim’ удален, но тип элемента входящего массива может быть получен с помощью отражения!
Ответ №4:
Вы могли бы сделать это, что не требует подавления каких-либо предупреждений.
public static <T> T[][] toTwoDim(Class<T[][]> clazz, T[] array)
{
int halfLength = array.length / 2;
T[][] ret = clazz.cast(Array.newInstance(clazz.getComponentType().getComponentType(), 2, halfLength 1));
System.arraycopy(array, 0, ret[0], 0, halfLength);
System.arraycopy(array, halfLength, ret[1], 0, array.length - halfLength);
return ret;
}