Как удалить ненужное выделение int при преобразовании двумерного массива в одномерный?

Всякий раз, когда я хочу преобразовать 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 и даже повышает эффективность моего кода.

Зависит от. Фиксированные размеры 2d-массива? Если так: да, мы можем использовать arrayCopy, чтобы улучшить этот много. Если нет, мы все равно можем делать вещи более эффективно, но не так эффективно, если 2-е измерение зафиксировано.

Mike 'Pomax' Kamermans 01.05.2018 22:21

Предположим, что двумерный массив действительно зафиксирован.

user7338524 01.05.2018 22:23
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
73
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Мы можем просто вычислить это напрямую

for (int x = 0; x < width; x++)
{
     for (int y = 0; y < height; y++)
     {
          oneDimensionalArray[x*height+y] = twoDimensionalArray[x][y];
     }
}

зачем вам это делать, просто arrayCopy целые вторичные массивы?

Mike 'Pomax' Kamermans 01.05.2018 22:24

Просто задал вопрос, как избавиться от index. Это не имеет особого значения, на мелочах это не займет много времени, на больших точках доступа все будет по-своему.

Probie 01.05.2018 22:26

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

Mike 'Pomax' Kamermans 01.05.2018 22:28

В текущей версии вопроса даже не упоминается слово «эффективный», в нем явно сказано удалить index ...

Probie 01.05.2018 22:41
Ответ принят как подходящий

Вы можете сделать это с помощью одного цикла:

for (int x = 0; x < width; x++) {
  System.arraycopy(twoDimensionalArray[x], 0, oneDimensionalArray, x*height, height);
}

Другой вопрос: System.arraycopy менее эффективен (с точки зрения производительности), чем ответ, опубликованный Probie?

user7338524 01.05.2018 22:27

@ToxicTV во всяком случае производительнее, не меньше.

Jeffrey Phillips Freeman 01.05.2018 22:28

Я просто хочу знать, потому что цикл в моей программе выполняется примерно десять тысяч раз.

user7338524 01.05.2018 22:28

arrayCopy является эффективным безумно. Это прямая копия памяти без каких-либо итераций.

Mike 'Pomax' Kamermans 01.05.2018 22:30

Я до сих пор не понимаю одного: что такое y в вашем ответе?

user7338524 01.05.2018 22:32

Вы говорите, что вам нужен только один цикл for, но может показаться, что вам все еще нужны два из них.

user7338524 01.05.2018 22:32

@ToxicTV вам нужен только один цикл явный.

Andy Turner 01.05.2018 22:33

Что именно означает цикл явный?

user7338524 01.05.2018 22:35

Я был бы рад, если бы вы добавили к своему ответу небольшой пример!

user7338524 01.05.2018 22:36

Небольшой пример чего? Это весь необходимый код.

Andy Turner 01.05.2018 22:36

Но чем заменить переменную y?

user7338524 01.05.2018 22:37

Явный цикл - это тот, который вы фактически пишете в цикле. System.arraycopy может содержать циклы, но вы не видите их в этом коде: по сути, это просто вызов метода, как и любой другой; явный цикл - это for.

Andy Turner 01.05.2018 22:37

@ToxicTV где второй шлейф? arrayCopy выдает команду копирования области памяти, нет «цикла по записям внутри скопированной части массива», JVM буквально просто копирует весь сегмент памяти оптом, сообщая ОС сделать это для нее, на основе тот факт, что он знает, как байты должны выравниваться (что он делает, потому что java является типобезопасным, а arrayCopy несовместим с типом является ошибкой)

Mike 'Pomax' Kamermans 01.05.2018 22:37

Хорошо, я понимаю! Мне просто было интересно, что означала переменная y в его ответе, но позже он изменил ее на «высоту» массива!

user7338524 01.05.2018 22:39

Также обратите внимание, что если массив не имеет фиксированных размеров или просто «неизвестен», то мы можем назначить width из twoDimensionalArray.length и height внутри цикла из twoDimensionalArray[x].length, и все будет по-прежнему работать. Единственная сложная часть - это предварительное выделение достаточно длинного массива для копирования (в этом случае вам может потребоваться начальный цикл, который подсчитывает все длины «столбцов», чтобы вы могли вычислить длину целевого массива)

Mike 'Pomax' Kamermans 02.05.2018 08:44

Другие вопросы по теме