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 arrayUm 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 rowUm 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 StringBuilderDas 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
| Ziel | Methode |
|---|---|
| Genaues Duplikat eines 1D-Arrays | arr.clone() oder Arrays.copyOf(arr, arr.length) |
| Größe beim Kopieren ändern (vergrößern/verkleinern) | Arrays.copyOf(arr, newLength) |
| Ausschnitt — Teil eines Arrays kopieren | Arrays.copyOfRange(arr, from, to) |
| In einen bestimmten Bereich eines bestehenden Arrays kopieren | System.arraycopy(...) |
| 2D-Array tief kopieren | jede Zeile in einer Schleife klonen |
| Kopieren und transformieren | Streams (map, filter, dann toArray) |
Ein vollständiges Beispiel
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.