Всякий раз, когда я хочу преобразовать int[][]
в массив int[]
, я следую процедуре, показанной ниже.
final int[][] source = new int[3][3];
final int[] array = new int[9];
// I allocate an int that represents the current index of the int[] array.
int index = 0;
// Afterwards I iterate over the `int[][]` array.
for (int x = 0; x < 3; x++)
{
for (int y = 0; y < 3; y++)
{
array[++index] = source[x][y];
}
}
Код выполняет свою работу, но я хочу знать, есть ли лучшее решение моей проблемы, которое эффективно устраняет переменную index
и даже повышает эффективность моего кода.
Предположим, что двумерный массив действительно зафиксирован.
Мы можем просто вычислить это напрямую
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
oneDimensionalArray[x*height+y] = twoDimensionalArray[x][y];
}
}
зачем вам это делать, просто arrayCopy целые вторичные массивы?
Просто задал вопрос, как избавиться от index
. Это не имеет особого значения, на мелочах это не займет много времени, на больших точках доступа все будет по-своему.
вопрос в том, как делать вещи эффективно. Простое избавление от index
на самом деле не является полезным ответом для этой цели, это немного ускоряет работу, но далеко не так быстро, как обычная Java уже позволяет это быть.
В текущей версии вопроса даже не упоминается слово «эффективный», в нем явно сказано удалить index
...
Вы можете сделать это с помощью одного цикла:
for (int x = 0; x < width; x++) {
System.arraycopy(twoDimensionalArray[x], 0, oneDimensionalArray, x*height, height);
}
Другой вопрос: System.arraycopy
менее эффективен (с точки зрения производительности), чем ответ, опубликованный Probie?
@ToxicTV во всяком случае производительнее, не меньше.
Я просто хочу знать, потому что цикл в моей программе выполняется примерно десять тысяч раз.
arrayCopy является эффективным безумно. Это прямая копия памяти без каких-либо итераций.
Я до сих пор не понимаю одного: что такое y
в вашем ответе?
Вы говорите, что вам нужен только один цикл for, но может показаться, что вам все еще нужны два из них.
@ToxicTV вам нужен только один цикл явный.
Что именно означает цикл явный?
Я был бы рад, если бы вы добавили к своему ответу небольшой пример!
Небольшой пример чего? Это весь необходимый код.
Но чем заменить переменную y
?
Явный цикл - это тот, который вы фактически пишете в цикле. System.arraycopy
может содержать циклы, но вы не видите их в этом коде: по сути, это просто вызов метода, как и любой другой; явный цикл - это for
.
@ToxicTV где второй шлейф? arrayCopy выдает команду копирования области памяти, нет «цикла по записям внутри скопированной части массива», JVM буквально просто копирует весь сегмент памяти оптом, сообщая ОС сделать это для нее, на основе тот факт, что он знает, как байты должны выравниваться (что он делает, потому что java является типобезопасным, а arrayCopy несовместим с типом является ошибкой)
Хорошо, я понимаю! Мне просто было интересно, что означала переменная y
в его ответе, но позже он изменил ее на «высоту» массива!
Также обратите внимание, что если массив не имеет фиксированных размеров или просто «неизвестен», то мы можем назначить width
из twoDimensionalArray.length
и height
внутри цикла из twoDimensionalArray[x].length
, и все будет по-прежнему работать. Единственная сложная часть - это предварительное выделение достаточно длинного массива для копирования (в этом случае вам может потребоваться начальный цикл, который подсчитывает все длины «столбцов», чтобы вы могли вычислить длину целевого массива)
Зависит от. Фиксированные размеры 2d-массива? Если так: да, мы можем использовать arrayCopy, чтобы улучшить этот много. Если нет, мы все равно можем делать вещи более эффективно, но не так эффективно, если 2-е измерение зафиксировано.