W3docs

Arrays kopieren in Java

Java-Arrays kopieren mit System.arraycopy, Arrays.copyOf, clone und Stream-basiertem Kopieren.

Eine Array-Variable einer anderen zuzuweisen kopiert nichts — es entstehen lediglich zwei Namen, die auf dasselbe zugrunde liegende Array zeigen:

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

Um eine unabhängige Kopie zu erhalten, muss man diese explizit anfordern. Java bietet dafür mehrere Möglichkeiten, jede für eine andere Situation geeignet: vollständiges Duplikat, Größenänderung beim Kopieren, Ausschnitt, Kopieren zwischen zwei bestehenden Arrays. Die meisten davon befinden sich in der Arrays-Hilfsklasse, daher wird in den folgenden Beispielen import java.util.Arrays; vorausgesetzt.

Arrays.copyOf — Duplikat oder Größenänderung

Nimmt die Quelle und eine Ziellänge. Wenn die neue Länge übereinstimmt, erhält man eine saubere Kopie. Ist sie größer, werden die zusätzlichen Felder mit Standardwerten gefüllt (0, false, null); ist sie kleiner, wird der hintere Teil abgeschnitten.

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}

So „vergrößert" man ein Array mit fester Größe — man weist ein größeres zu und kopiert.

Arrays.copyOfRange — Ausschnitt

Kopiert einen halboffenen Bereich [from, to):

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

to darf die Länge der Quelle überschreiten — zusätzliche Felder werden als Standardwerte zurückgegeben. So kann man in einem Aufruf ausschneiden und auffüllen.

System.arraycopy — in ein bestehendes Array kopieren

Das unterste Grundelement: einen Bereich eines Arrays in einen Bereich eines anderen kopieren. Keine neue Speicherallokation, kein Rückgabewert — beide Arrays müssen bereits vorhanden sein.

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}

Die Argumente sind (src, srcStart, dst, dstStart, length). Verwende dies, wenn man Daten an einem bestimmten Offset platzieren möchte oder Elemente innerhalb desselben Arrays verschiebt — System.arraycopy(arr, i, arr, i + 1, length - i - 1) verschiebt einen Ausschnitt um eins nach rechts, um Platz für ein Einfügeelement zu schaffen. Überlappende Bereiche innerhalb eines einzelnen Arrays werden unterstützt und korrekt behandelt.

clone() — schnelle vollständige Kopie

Jedes Array hat eine clone()-Methode, die ein neues Array gleicher Länge und gleichen Inhalts zurückgibt:

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

Für eindimensionale Arrays ist clone() der kürzeste und klarste Weg zur Duplikation. Der Rückgabetyp ist derselbe wie die Quelle — kein Cast erforderlich.

Für mehrdimensionale Arrays ist clone() flach: Es kopiert das äußere Array, aber die Zeilen sind nach wie vor die ursprünglichen Referenzen:

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

Um ein 2D-Array tief zu kopieren, klont man jede Zeile einzeln:

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

Eine Stream-Variante: Arrays.stream(grid).map(int[]::clone).toArray(int[][]::new).

Streams

Für object arrays erzeugt Arrays.stream(arr).toArray(T[]::new) eine Kopie:

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

Für primitive Arrays verwendet man den spezialisierten Stream:

import java.util.stream.IntStream;

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

Streams sind schwerer als copyOf oder clone() und existieren hauptsächlich für den Transformations-Fall — .map(...) oder .filter(...) in der Pipeline — nicht für das schlichte Duplizieren.

Referenzkopien vs. tiefe Kopien

Bei primitiven Typen ist jede Kopie vollständig unabhängig — die Werte selbst werden dupliziert. Bei object arrays sind alle behandelten Kopiermethoden flach: Sie duplizieren das Array der Referenzen, aber jede Referenz zeigt noch auf dasselbe Objekt wie das Original.

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

Das ist normalerweise in Ordnung — Strings, Integers und alles Unveränderliche kann sicher geteilt werden. Wenn die Elemente veränderlich sind und man unabhängige Objekte benötigt, muss man sie selbst kopieren:

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

Wahl der Kopiermethode

ZielMethode
Genaues Duplikat eines 1D-Arraysarr.clone() oder Arrays.copyOf(arr, arr.length)
Größe beim Kopieren ändern (vergrößern/verkleinern)Arrays.copyOf(arr, newLength)
Ausschnitt — Teil eines Arrays kopierenArrays.copyOfRange(arr, from, to)
In einen bestimmten Bereich eines bestehenden Arrays kopierenSystem.arraycopy(...)
2D-Array tief kopierenjede Zeile in einer Schleife klonen
Kopieren und transformierenStreams (map, filter, dann toArray)

Ein vollständiges Beispiel

java— editable, runs on the server

Was kommt als Nächstes

Du kannst jetzt Arrays erstellen, durchlaufen, durchsuchen, sortieren und kopieren — das vollständige Werkzeugset für die Arbeit mit Javas Containern fester Größe. Als Nächstes folgt der Teil über Methoden: wie man Code in benannte, wiederverwendbare Einheiten verpackt, die Parameter entgegennehmen und Werte zurückgeben.

Übungen

Übung
Was gibt arr.clone() für ein int[][] zurück?
Was gibt arr.clone() für ein int[][] zurück?
Was this page helpful?