HOWTO · Java

Element aus Array entfernen und dann andere Elemente in Java verschieben

In diesem Artikel wird beschrieben, wie Sie ein Element aus einem Array entfernen und das Array verschieben.

Auf dieser Seite

Arrays in Java haben eine feste Länge. Werden Werte nach links verschoben, schließt das zwar eine Lücke, verkürzt aber das Array nicht. Für ein Array mit einem Element weniger müssen Sie ein kleineres Array erstellen oder eine dynamisch vergrößerbare Sammlung verwenden. Die folgenden Beispiele entfernen ein Element anhand seines nullbasierten Index; im letzten Abschnitt erfahren Sie, wie Sie ein Element anhand seines Werts entfernen.

Kopieren Sie jedes Element nach dem ausgewählten Index in den jeweils vorherigen Platz und erstellen Sie anschließend mit Arrays.copyOf das kürzere Ergebnis. Während des Verschiebens wird das ursprüngliche Array verändert. Soll es unverändert verfügbar bleiben, legen Sie daher zuerst eine separate Kopie an.

Der gültige Indexbereich reicht von 0 bis array.length - 1. Dieses Beispiel prüft den Index, bevor es darauf zugreift. Liegt er außerhalb dieses Bereichs, bleibt das Array unverändert und eine Meldung wird ausgegeben. Die Meldung Index out of bounds im Code bleibt auf Englisch.

Arrays in Java haben eine feste Länge. Werden spätere Werte über ein Element geschrieben, rücken die übrigen Werte nach links, aber das Array behält seine ursprüngliche Länge. Für ein Array mit einem Element weniger müssen Sie den verschobenen Anfangsbereich in ein neues Array kopieren. Führen Sie dieses Beispiel aus:

Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.

import java.util.Arrays;

public class Main {
  public static void main(String[] args) {
    int[] array = {1, 2, 3, 4, 5};
    int indexToRemove = 2;

    if (indexToRemove >= 0 && indexToRemove < array.length) {
      for (int i = indexToRemove; i < array.length - 1; i++) {
        array[i] = array[i + 1];
      }
      array = Arrays.copyOf(array, array.length - 1);
      System.out.println(Arrays.toString(array));
    } else {
      System.out.println("Index out of bounds");
    }
  }
}

Ausgabe:

[1, 2, 4, 5]

Die Schleife endet beim vorletzten ursprünglichen Index, weil jeder Durchlauf array[i + 1] liest. Nach dem Verschieben enthält das alte letzte Feld einen doppelten Wert. Arrays.copyOf lässt dieses Feld weg, indem die Methode ein Array erstellt, das ein Element kürzer ist. Auch das Entfernen des letzten Elements funktioniert: Die Schleife wird kein einziges Mal durchlaufen, und die Kopie lässt das letzte Feld direkt weg.

Mit System.arraycopy() um einen Index herumkopieren

Mit System.arraycopy() lassen sich der Bereich vor dem entfernten Element und der Bereich danach in getrennte Abschnitte eines neuen Arrays kopieren. Die Argumente sind Quellarray, Quellposition, Zielarray, Zielposition und Anzahl der zu kopierenden Elemente. Die Länge der ersten Kopie entspricht dem Index des entfernten Elements; die Länge der zweiten ist array.length - indexToRemove - 1.

Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.

import java.util.Arrays;

public class Main {
  public static void main(String[] args) {
    int[] array = {2, 4, 6, 8, 10};
    int indexToRemove = 2;

    if (indexToRemove >= 0 && indexToRemove < array.length) {
      int[] result = new int[array.length - 1];
      System.arraycopy(array, 0, result, 0, indexToRemove);
      int elementsAfter = array.length - indexToRemove - 1;
      System.arraycopy(array, indexToRemove + 1, result, indexToRemove, elementsAfter);
      System.out.println(Arrays.toString(result));
    } else {
      System.out.println("Index out of bounds");
    }
  }
}

Ausgabe:

[2, 4, 8, 10]

Das Zielarray hat hier bereits die gewünschte Länge, sodass am Ende keine zusätzlichen Standardwerte enthalten sind. System.arraycopy() unterstützt auch überlappende Bereiche, wenn Quell- und Zielarray dasselbe Array sind; Java führt die Kopie sicher aus. Beim Kopieren in ein separates Ergebnisarray, wie im Beispiel, sind der beizubehaltende Anfangs- und Endbereich klar erkennbar.

Ein Element über eine ArrayList entfernen

Verwenden Sie ArrayList<Integer>, wenn die Daten bereits in einer Sammlung liegen oder mehrere Elemente hinzugefügt und entfernt werden sollen. Ein int[] lässt sich nicht direkt mit Arrays.asList als Liste von Integer-Werten übergeben: Primitive Arrays werden dabei als einzelnes Objekt behandelt. Verpacken Sie die Werte in Integer[], erstellen Sie daraus die Liste, entfernen Sie das Element anhand seines Index und wandeln Sie die Liste anschließend zurück in int[] um.

Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.

import java.util.ArrayList;
import java.util.Arrays;

public class Main {
  public static void main(String[] args) {
    int[] array = {1, 2, 3, 4, 5};
    int indexToRemove = 2;

    if (indexToRemove >= 0 && indexToRemove < array.length) {
      Integer[] boxed = Arrays.stream(array).boxed().toArray(Integer[]::new);
      ArrayList<Integer> values = new ArrayList<>(Arrays.asList(boxed));
      values.remove(indexToRemove);
      int[] result = values.stream().mapToInt(Integer::intValue).toArray();
      System.out.println(Arrays.toString(result));
    } else {
      System.out.println("Index out of bounds");
    }
  }
}

Ausgabe:

[1, 2, 4, 5]

values.remove(indexToRemove) wählt die Überladung, die das Element an der angegebenen Position entfernt. Die Rückumwandlung in int[] ist nötig, weil die Liste verpackte Integer-Objekte enthält, während die Quelle primitive int-Werte verwendet. Dieser Weg ist praktisch, erstellt aber sowohl eine Liste als auch ein neues Array. Bei einer einzelnen Entfernung aus einem vorhandenen int[] vermeiden beide Array-Kopieransätze die Umwandlung in eine Sammlung.

Nach Index oder Wert auswählen und Sonderfälle behandeln

Die Beispiele entfernen jeweils ein Element anhand seines nullbasierten Index. Ein gültiger Index erfüllt index >= 0 && index < array.length. Legen Sie fest, wie der aufrufende Code reagieren soll, wenn diese Bedingung nicht erfüllt ist: das ursprüngliche Array zurückgeben, einen Status zurückgeben oder das Problem melden. Greifen Sie erst dann auf array[index] zu, wenn die Prüfung erfolgreich war. Ein leeres Array hat keinen gültigen Index; dieselbe Prüfung weist daher jeden Index sicher zurück.

Um ein Element anhand seines Werts zu entfernen, suchen Sie den ersten passenden Index und verwenden Sie anschließend dasselbe Verfahren zum Verschieben und Verkleinern. Dieses Beispiel entfernt nur das erste Vorkommen. Wird kein passender Wert gefunden, bleibt das ursprüngliche Array unverändert; weitere gleiche Werte nach dem ersten bleiben im Ergebnis.

Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.

import java.util.Arrays;

public class Main {
  public static void main(String[] args) {
    int[] array = {3, 7, 3, 9};
    int target = 3;
    int indexToRemove = -1;

    for (int i = 0; i < array.length; i++) {
      if (array[i] == target) {
        indexToRemove = i;
        break;
      }
    }

    if (indexToRemove >= 0) {
      int[] result = new int[array.length - 1];
      for (int i = 0; i < indexToRemove; i++) {
        result[i] = array[i];
      }
      for (int i = indexToRemove + 1; i < array.length; i++) {
        result[i - 1] = array[i];
      }
      array = result;
    }

    System.out.println(Arrays.toString(array));
  }
}

Bei dieser Eingabe wird die erste 3 entfernt; das Ergebnis lautet [7, 3, 9]. Ist target nicht vorhanden, bleibt indexToRemove auf -1, die Kopie wird übersprungen und das ursprüngliche Array unverändert ausgegeben. Um stattdessen alle passenden Werte zu entfernen, zählen Sie die nicht übereinstimmenden Werte, um die Größe des Ergebnisarrays zu bestimmen, und kopieren Sie anschließend nur diese Werte.

Wählen Sie die Schleife, wenn Sie jede Verschiebung nachvollziehen und steuern möchten. System.arraycopy() eignet sich, wenn ein korrekt dimensioniertes Array aus zwei Bereichen erstellt werden soll. Verwenden Sie ArrayList, wenn der umgebende Code ohnehin eine dynamisch vergrößerbare Sammlung oder mehrere Änderungen benötigt. Alle drei Ansätze erzeugen eine neue logische Folge ohne das entfernte Element; nur die erste Schleife verändert zusätzlich den Inhalt des Eingabearrays, bevor sie eine kürzere Kopie zurückgibt.