Как мне скопировать 2-мерный массив в Java? - PullRequest
34 голосов
/ 11 апреля 2011

Мне нужно сделать копию довольно большого двухмерного массива для проекта, над которым я работаю.У меня есть два 2D-массива:

int[][]current;
int[][]old;

У меня также есть два метода для копирования.Мне нужно скопировать массив, потому что текущий регулярно обновляется.

public void old(){
  old=current
}

и

public void keepold(){
  current=old
}

Однако это не работает.Если бы я должен был назвать старый, обновить текущее, а затем вызвать keepold, текущий не равен первоначальному.С чего бы это?

Спасибо

Ответы [ 12 ]

38 голосов
/ 11 апреля 2011

current=old или old=current заставляет два массива ссылаться на одну и ту же вещь, поэтому, если вы впоследствии измените current, будет изменена и old. Чтобы скопировать содержимое массива в другой массив, используйте цикл for

for(int i=0; i<old.length; i++)
  for(int j=0; j<old[i].length; j++)
    old[i][j]=current[i][j];

PS: для одномерного массива вы можете избежать создания собственного цикла for, используя Arrays.copyOf

22 голосов
/ 10 декабря 2012
/**
 * Clones the provided array
 * 
 * @param src
 * @return a new clone of the provided array
 */
public static int[][] cloneArray(int[][] src) {
    int length = src.length;
    int[][] target = new int[length][src[0].length];
    for (int i = 0; i < length; i++) {
        System.arraycopy(src[i], 0, target[i], 0, src[i].length);
    }
    return target;
}

Можно ли изменить этот код для поддержки n-мерных массивов объектов ?

Вам нужно будет поддерживать произвольные длины массивов и проверять, имеют ли src и destination одинаковые размеры, , и вам также нужно будет копировать каждый элемент каждого массива рекурсивно , в случае, если Объект был также массивом.

Прошло много времени с тех пор, как я это опубликовал, но я нашел хороший пример одного способа создания класса n-мерного массива. Класс принимает ноль или более целых чисел в конструкторе, определяя соответствующий размер каждого измерения. Класс использует базовый flat array Object[] и вычисляет индекс каждого элемента, используя измерения и массив множителей. (Вот как создаются массивы на языке программирования C.)

Копировать экземпляр NDimensionalArray так же просто, как копировать любой другой 2D-массив, хотя вы должны утверждать, что каждый объект NDimensionalArray имеет одинаковые размеры. Это, вероятно, самый простой способ сделать это, поскольку нет рекурсии, и это значительно упрощает представление и доступ.

8 голосов
/ 20 ноября 2018

Начиная с Java 8, используя API потоков:

int[][] copy = Arrays.stream(matrix).map(r -> r.clone()).toArray(int[][]::new);

r относится к row в 2D-матрице.

7 голосов
/ 23 ноября 2012

Я решил написать простую функцию для копирования многомерных массивов int с помощью System.arraycopy

public static void arrayCopy(int[][] aSource, int[][] aDestination) {
    for (int i = 0; i < aSource.length; i++) {
        System.arraycopy(aSource[i], 0, aDestination[i], 0, aSource[i].length);
    }
}

или фактически я улучшил его для моего случая использования:

/**
 * Clones the provided array
 * 
 * @param src
 * @return a new clone of the provided array
 */
public static int[][] cloneArray(int[][] src) {
    int length = src.length;
    int[][] target = new int[length][src[0].length];
    for (int i = 0; i < length; i++) {
        System.arraycopy(src[i], 0, target[i], 0, src[i].length);
    }
    return target;
}
4 голосов
/ 05 апреля 2015

Вы также можете сделать следующее:

public static int[][] copy(int[][] src) {
    int[][] dst = new int[src.length][];
    for (int i = 0; i < src.length; i++) {
        dst[i] = Arrays.copyOf(src[i], src[i].length);
    }
    return dst;
}
1 голос
/ 27 июня 2019

Используя Java 8, это можно сделать с помощью

`int[][] destination=Arrays.stream(source)
                    .map(a ->  Arrays.copyOf(a, a.length))
                    .toArray(int[][]::new);
0 голосов
/ 27 августа 2016

Вот как вы можете сделать это, используя циклы.

public static int[][] makeCopy(int[][] array){
    b=new int[array.length][];

    for(int row=0; row<array.length; ++row){
        b[row]=new int[array[row].length];
        for(int col=0; col<b[row].length; ++col){
            b[row][col]=array[row][col];
        }
    }
    return b;
}
0 голосов
/ 11 июля 2015

Я использую эту функцию:

public static int[][] copy(final int[][] array) {
    if (array != null) {
        final int[][] copy = new int[array.length][];

        for (int i = 0; i < array.length; i++) {
            final int[] row = array[i];

            copy[i] = new int[row.length];
            System.arraycopy(row, 0, copy[i], 0, row.length);
        }

        return copy;
    }

    return null;
}

Большим преимуществом этого подхода является то, что он также может копировать массивы, не имеющие одинакового количества строк, например:

final int[][] array = new int[][] { { 5, 3, 6 }, { 1 } };
0 голосов
/ 29 мая 2013
public  static byte[][] arrayCopy(byte[][] arr){
    if(arr!=null){
        int[][] arrCopy = new int[arr.length][] ;
        System.arraycopy(arr, 0, arrCopy, 0, arr.length);
        return arrCopy;
    }else { return new int[][]{};}
}
0 голосов
/ 11 апреля 2011

Вы можете попробовать следующий код,

public void multiArrayCopy(int[][] source,int[][] destination){
destination=source.clone();}

Надеюсь, что это работает.

...