HOWTO · Java
Erstellen ein Subarray in Java
Dieses Tutorial zeigt, wie Sie in Java ein Subarray aus einem anderen Array erstellen
Auf dieser Seite
Ein Subarray ist ein zusammenhängender Bereich, der in ein separates Array kopiert wird. Arrays in Java verwenden nullbasierte Indizes: Der Startindex ist eingeschlossen, und der Endindex bezeichnet die Position nach dem letzten kopierten Element. Diese Beispiele verwenden die Indizes 1 bis 3 des Quellarrays.
Was ein Subarray in Java bedeutet
Beim Kopieren eines Bereichs entsteht ein neues Array und keine Ansicht auf das ursprüngliche Array. Eine Änderung an einem Element eines kopierten int[] wirkt sich daher nicht auf das Quellarray aus. Bei Objektarrays enthält das neue Array dieselben Objektreferenzen. Änderungen am Objekt selbst können deshalb über beide Arrays sichtbar sein.
Die übliche Bereichsnotation lautet [start, end): start ist eingeschlossen und end ausgeschlossen. Bei einem Quellarray mit neun Elementen reichen die Indizes von 0 bis 8. Der Bereich von 2 bis 5 umfasst drei Elemente. Berücksichtige diese Konvention, wenn du aus einer gewünschten Elementanzahl den Endindex ableitest: end ist start + length.
Ein Subarray mit Arrays.copyOfRange erstellen
Arrays.copyOfRange ist eine knappe Lösung, wenn du ein neu angelegtes Array benötigst. Übergib in dieser Reihenfolge das Quellarray, den eingeschlossenen Startindex und den ausgeschlossenen Endindex. Führe dieses Beispiel aus:
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
import java.util.Arrays;
public class SubarrayExample {
public static void main(String[] args) {
int[] source = {10, 20, 30, 40, 50, 60};
int[] part = Arrays.copyOfRange(source, 1, 4);
System.out.println(Arrays.toString(part));
}
}
[20, 30, 40]
Das Ergebnis ist ein separates Array mit den Elementen an den Quellindizes 1, 2 und 3. Das Element am Endindex wird nicht kopiert. Ein Endindex, der über die Länge des Quellarrays hinausgeht, ist zulässig; das Ergebnis wird dann mit dem Standardwert des Komponententyps aufgefüllt (0 für int, null für einen Referenztyp). Der Startindex muss innerhalb des Arrays oder genau an dessen Ende liegen, und der Endindex darf nicht vor dem Startindex liegen. Soll ein Endindex jenseits der Quelllänge stattdessen einen Fehler auslösen, prüfe ihn vor dem Methodenaufruf.
Ein Subarray mit System.arraycopy erstellen
Verwende System.arraycopy, wenn du das Zielarray oder dessen Einfügeposition selbst festlegen musst. Die fünf Argumente sind: Quellarray, Quellposition, Zielarray, Zielposition und Anzahl der Elemente. Das letzte Argument ist eine Anzahl und kein Endindex; ab der Zielposition muss das Zielarray Platz für diese Anzahl an Elementen bieten.
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
import java.util.Arrays;
public class SubarrayWithArraycopy {
public static void main(String[] args) {
int[] source = {10, 20, 30, 40, 50, 60};
int start = 1;
int length = 3;
int[] part = new int[length];
System.arraycopy(source, start, part, 0, length);
System.out.println(Arrays.toString(part));
}
}
Hier endet der kopierte Bereich bei start + length, also bei 4; dieser Index ist ausgeschlossen. Lege das Zielarray anhand der gewünschten Kopierlänge an. Java prüft Positionen und Längen; inkompatible Elementtypen bei Referenzarrays können außerdem einen Array-Store-Fehler verursachen.
Ein Subarray mit einer Schleife erstellen
Eine Schleife macht den Zielversatz deutlich und ermöglicht es, jedes Element beim Kopieren zu prüfen oder umzuwandeln. Beim Bereich [start, end) beginnt der Zielindex i - start bei null und steigt gemeinsam mit dem Quellindex an.
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
import java.util.Arrays;
public class SubarrayWithLoop {
public static void main(String[] args) {
int[] source = {10, 20, 30, 40, 50, 60};
int start = 1;
int end = 4;
int[] part = new int[end - start];
for (int i = start; i < end; i++) {
part[i - start] = source[i];
}
System.out.println(Arrays.toString(part));
}
}
Die Schleife setzt voraus, dass die Indizes einen gültigen Bereich im Quellarray bezeichnen. Wenn sie aus einer Benutzereingabe stammen, prüfe sie vor dem Anlegen des Zielarrays. Anders als Arrays.copyOfRange füllt eine Schleife das Ergebnis nicht automatisch auf, wenn der angeforderte Endindex über die Quelllänge hinausgeht; ein Zugriff außerhalb des Arrays schlägt fehl. Eine Schleife eignet sich, wenn beim Kopieren zusätzlich eine Bedingung, eine Umwandlung oder eine andere eigene Regel angewendet werden soll.
Ein Subarray mit der Stream-API erstellen
Für ein int[] liefert IntStream.range(start, end) die Indizes ab dem eingeschlossenen Startindex bis zum ausgeschlossenen Endindex. Ordne jedem Index den zugehörigen Wert aus dem Quellarray zu und sammle die Werte anschließend mit toArray() in einem neuen primitiven Array.
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
import java.util.Arrays;
import java.util.stream.IntStream;
public class SubarrayWithStream {
public static void main(String[] args) {
int[] source = {10, 20, 30, 40, 50, 60};
int[] part = IntStream.range(1, 4)
.map(i -> source[i])
.toArray();
System.out.println(Arrays.toString(part));
}
}
Hier gilt dieselbe Bereichskonvention wie in den vorherigen Beispielen. Die vom Stream erzeugten Indizes müssen weiterhin für das Quellarray gültig sein. Verwende diesen Ansatz, wenn du die Auswahl ohnehin als indexbasierte Verarbeitungskette ausdrücken möchtest. Ein Stream macht die Prüfung des Bereichs nicht überflüssig.
Das passende Verfahren für deinen Anwendungsfall auswählen
Wähle Arrays.copyOfRange, wenn du einen Bereich direkt kopieren und dafür ein Array anlegen möchtest, insbesondere wenn das Auffüllen über den Endindex hinaus nützlich ist. Wähle System.arraycopy, wenn du bereits ein Zielarray hast oder die kopierten Werte an einer von null verschiedenen Zielposition einfügen musst. Eine Schleife eignet sich, wenn die Kopie eine eigene Verarbeitung jedes Elements erfordert. Wähle die Stream-API, wenn sich indexbasierte Umwandlungen damit leichter nachvollziehbar ausdrücken lassen.
Arrays.copyOfRange, die Schleife und das Stream-Beispiel legen jeweils ein neues Array an. System.arraycopy kopiert in das von dir angegebene Zielarray und erzeugt daher nur dann einen neuen Container, wenn du dafür selbst einen anlegst. Bei einem primitiven Array werden die Werte kopiert. Bei einem Objektarray werden die Referenzen kopiert, nicht die referenzierten Objekte selbst. Wähle das Verfahren nach dem benötigten Bereichsverhalten, der Kontrolle über das Zielarray und der zusätzlichen Verarbeitung aus; diese Beispiele vergleichen nicht die Leistung.