W3docs

Copier des tableaux en Java

Copiez des tableaux Java avec System.arraycopy, Arrays.copyOf, clone et les streams.

Affecter une variable de tableau à une autre ne copie rien — cela crée simplement deux noms pointant vers le même tableau sous-jacent :

int[] a = {1, 2, 3};
int[] b = a;
b[0] = 99;
System.out.println(a[0]);   // 99 — same array

Pour obtenir une copie indépendante, vous devez en demander une explicitement. Java propose plusieurs façons de procéder, chacune adaptée à une situation différente : duplication complète, redimensionnement lors de la copie, extraction d'une tranche, copie entre deux tableaux existants. La plupart de ces méthodes se trouvent sur la classe utilitaire Arrays, donc un import java.util.Arrays; est supposé dans les exemples ci-dessous.

Arrays.copyOf — dupliquer ou redimensionner

Prend la source et une longueur cible. Si la nouvelle longueur correspond, vous obtenez une copie propre. Si elle est plus grande, les emplacements supplémentaires sont remplis avec des valeurs par défaut (0, false, null) ; si elle est plus petite, la queue est abandonnée.

import java.util.Arrays;

int[] data = {1, 2, 3, 4, 5};
int[] same   = Arrays.copyOf(data, data.length);   // {1, 2, 3, 4, 5}
int[] grown  = Arrays.copyOf(data, 8);             // {1, 2, 3, 4, 5, 0, 0, 0}
int[] shrunk = Arrays.copyOf(data, 3);             // {1, 2, 3}

C'est ainsi que l'on « agrandit » un tableau de taille fixe — on en alloue un plus grand et on copie.

Arrays.copyOfRange — extraire une tranche

Copie une plage semi-ouverte [from, to) :

int[] data = {1, 2, 3, 4, 5};
int[] middle = Arrays.copyOfRange(data, 1, 4);   // {2, 3, 4}

to peut dépasser la longueur de la source — les emplacements supplémentaires seront remplis avec des valeurs par défaut. Vous pouvez donc extraire une tranche et remplir en un seul appel.

System.arraycopy — copier dans un tableau existant

La primitive de plus bas niveau : copier une plage d'un tableau dans une plage d'un autre. Pas de nouvelle allocation, pas de valeur de retour — les deux tableaux doivent déjà exister.

int[] src = {10, 20, 30, 40, 50};
int[] dst = new int[8];
System.arraycopy(src, 1, dst, 3, 3);
// dst is now {0, 0, 0, 20, 30, 40, 0, 0}

Les arguments sont (src, srcStart, dst, dstStart, length). Utilisez ceci lorsque vous souhaitez placer des données à un décalage spécifique, ou lorsque vous déplacez des éléments à l'intérieur du même tableau — System.arraycopy(arr, i, arr, i + 1, length - i - 1) décale une tranche d'un cran vers la droite pour faire de la place à une insertion. Les plages qui se chevauchent au sein d'un même tableau sont prises en charge et gérées correctement.

clone() — copie complète rapide

Chaque tableau possède une méthode clone() qui retourne un nouveau tableau de même longueur et contenu :

int[] data = {1, 2, 3};
int[] copy = data.clone();

Pour les tableaux unidimensionnels, clone() est le moyen le plus court et le plus clair de dupliquer. Le type de retour est le même que la source — aucun cast nécessaire.

Pour les tableaux multidimensionnels, clone() est superficiel : il copie le tableau externe, mais les lignes restent les références originales :

int[][] grid = {{1, 2}, {3, 4}};
int[][] shallow = grid.clone();
shallow[0][0] = 99;
System.out.println(grid[0][0]);   // 99 — same inner row

Pour effectuer une copie profonde d'un tableau 2D, clonez chaque ligne à tour de rôle :

int[][] deep = new int[grid.length][];
for (int r = 0; r < grid.length; r++) deep[r] = grid[r].clone();

Une version avec stream : Arrays.stream(grid).map(int[]::clone).toArray(int[][]::new).

Streams

Pour les tableaux d'objets, Arrays.stream(arr).toArray(T[]::new) produit une copie :

String[] names = {"Ada", "Linus", "Grace"};
String[] copy = Arrays.stream(names).toArray(String[]::new);

Pour les tableaux de primitives, utilisez le stream spécialisé :

import java.util.stream.IntStream;

int[] data = {1, 2, 3, 4, 5};
int[] copy = IntStream.of(data).toArray();

Les streams sont plus lourds que copyOf ou clone() et existent principalement pour le cas de transformation.map(...) ou .filter(...) en milieu de pipeline — pas pour la simple duplication.

Copies par référence vs copies profondes

Pour les primitives, chaque copie est totalement indépendante — les valeurs elles-mêmes sont dupliquées. Pour les tableaux d'objets, toutes les méthodes de copie que nous avons vues sont superficielles : elles dupliquent le tableau de références, mais chaque référence pointe toujours vers le même objet que l'original.

StringBuilder[] src = { new StringBuilder("hi") };
StringBuilder[] copy = src.clone();
copy[0].append(" there");
System.out.println(src[0]);   // "hi there" — same StringBuilder

C'est généralement correct — les Strings, les Integers et tout ce qui est immuable peut être partagé en toute sécurité. Si les éléments sont mutables et que vous avez besoin d'objets indépendants, vous devez les copier vous-même :

StringBuilder[] deep = new StringBuilder[src.length];
for (int i = 0; i < src.length; i++) deep[i] = new StringBuilder(src[i]);

Choisir une méthode de copie

Ce que vous voulezUtiliser
Duplication exacte d'un tableau 1Darr.clone() ou Arrays.copyOf(arr, arr.length)
Redimensionner lors de la copie (agrandir/réduire)Arrays.copyOf(arr, newLength)
Tranche — copier une partie d'un tableauArrays.copyOfRange(arr, from, to)
Copier dans un emplacement d'un tableau existantSystem.arraycopy(...)
Copie profonde d'un tableau 2Dcloner chaque ligne dans une boucle
Copier et transformerstreams (map, filter, puis toArray)

Un exemple complet

java— editable, runs on the server

La suite

Vous savez maintenant créer, parcourir, rechercher, trier et copier des tableaux — la boîte à outils complète pour travailler avec les conteneurs de taille fixe de Java. La suite concerne les méthodes : comment regrouper du code dans des unités nommées et réutilisables qui prennent des paramètres et retournent des valeurs.

Pratique

Pratique
Que retourne arr.clone() pour un int[][]?
Que retourne arr.clone() pour un int[][]?
Was this page helpful?