web-dev-qa-db-fra.com

Comment copier un tableau à 2 dimensions en Java?

Je dois faire une copie d'un assez grand tableau 2 dimensions pour un projet sur lequel je travaille. J'ai deux tableaux 2D:

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

J'ai aussi deux méthodes pour faire la copie. J'ai besoin de copier le tableau car courant est mis à jour régulièrement.

public void old(){
  old=current
}

et

public void keepold(){
  current=old
}

Cependant, cela ne fonctionne pas. Si je devais appeler old, faire une mise à jour sur current, puis appeler keepold, current n’est pas égal à ce qu’il était à l’origine. Pourquoi serait-ce?

Merci

31
badcoder

current=old ou old=current fait en sorte que les deux tableaux se réfèrent à la même chose, donc si vous modifiez ultérieurement current, old sera également modifié. Pour copier le contenu d'un tableau dans un autre tableau, utilisez la boucle 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: Pour un tableau unidimensionnel, vous pouvez éviter de créer votre propre boucle for en utilisant Arrays.copyOf

37
Louis Rhys
/**
 * 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;
}

Est-il possible de modifier ce code pour prendre en charge les tableaux n-dimensionnels d'objets?

Vous auriez besoin de supporter des longueurs arbitraires de tableaux et de vérifier si le src et la destination ont les mêmes dimensions, et vous auriez également besoin de copier chaque élément de chaque tableau récursivement, au cas où l'objet serait aussi un tableau.

Cela fait longtemps que je n'ai pas posté ceci, mais j'ai trouvé un bel exemple d'une manière de créer une classe de tableau à n dimensions. La classe prend zéro ou plusieurs entiers dans le constructeur, en spécifiant la taille respective de chaque dimension. La classe utilise un flat tableau Object[] sous-jacent et calcule l'index de chaque élément à l'aide des dimensions et d'un tableau de multiplicateurs. (C’est ainsi que les tableaux sont réalisés dans le langage de programmation C.) 

Copier une instance de NDimensionalArray serait aussi simple que de copier tout autre tableau 2D, bien que vous deviez affirmer que chaque objet NDimensionalArray avait des dimensions égales. C'est probablement la façon la plus simple de le faire, car il n'y a pas de récursivité, ce qui simplifie considérablement la représentation et l'accès.

22
mbomb007

Je l'ai résolu en écrivant une fonction simple pour copier des tableaux multidimensionnels en utilisant 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);
    }
}

ou en fait je l'ai amélioré pour mon cas d'utilisation:

/**
 * 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;
}
6
Daniel Backman

Vous pouvez également faire comme suit:

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;
}
3
Johnny Lim

Depuis Java 8, en utilisant l’API de flux:

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

r fait référence à row dans la matrice 2D.

1
Gayan Weerakutti

Voici comment vous pouvez le faire en utilisant des boucles.

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
Arafe Zawad Sajid
current = old ;

Les opérations d'affectation ne copient pas les éléments d'un tableau dans un autre. Vous faites juste que la matrice current se réfère à la matrice old. Vous devez faire une copie sage de membre.

0
Mahesh

Les tableaux en Java sont des objets et tous les objets sont passés par référence . Afin de vraiment "copier" un tableau, au lieu de créer un autre nom pour un tableau, vous devez créer un nouveau tableau et copier toutes les valeurs. Notez que System.arrayCopy copie complètement les tableaux à une dimension, mais PAS les tableaux à 2 dimensions. La raison en est qu’un tableau 2D est en fait un tableau 1D de tableaux 1D et que arrayCopy copie des pointeurs sur les mêmes tableaux 1D internes.

0
Sajid

J'utilise cette fonction:

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;
}

Le gros avantage de cette approche est qu’elle peut également copier des tableaux qui n’ont pas le même nombre de lignes, tels que:

final int[][] array = new int[][] { { 5, 3, 6 }, { 1 } };
0
Niklas