0Pricing
Java Academy · Lektion

ListIterator und bidirektionales Durchlaufen

Verwenden Sie ListIterator, um Listen vorwärts und rückwärts zu durchlaufen und Elemente während der Iteration zu ändern.

ListIterator und bidirektionales Durchlaufen ist eine kostenlose Java Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Java Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.

ListIterator

ListIterator<T> erweitert Iterator<T> um das Durchlaufen in umgekehrter Richtung, die Positionierung über Indizes sowie die Möglichkeit, Elemente während der Iteration hinzuzufügen und zu ersetzen.

ListIterator API

Zusätzliche Methoden gegenüber Iterator: hasPrevious(), previous(), nextIndex(), previousIndex(), set(), add().

import java.util.*;

List<String> list = new ArrayList<>(List.of("A", "B", "C", "D"));
ListIterator<String> lit = list.listIterator();

// Forward traversal
while (lit.hasNext()) {
    System.out.print(lit.nextIndex() + ":" + lit.next() + " ");
}
// 0:A 1:B 2:C 3:D

System.out.println();

// Backward traversal
while (lit.hasPrevious()) {
    System.out.print(lit.previousIndex() + ":" + lit.previous() + " ");
}
// 3:D 2:C 1:B 0:A

An einer Position starten

Erstellen Sie mit listIterator(index) einen ListIterator, der an einem bestimmten Index startet.

List<Integer> nums = new ArrayList<>(List.of(10, 20, 30, 40, 50));

// Start at index 2 (30)
ListIterator<Integer> lit = nums.listIterator(2);

System.out.println(lit.next());     // 30
System.out.println(lit.next());     // 40
System.out.println(lit.previous()); // 40
System.out.println(lit.previous()); // 30
System.out.println(lit.previous()); // 20

set() während der Iteration

set() ersetzt das letzte von next() oder previous() zurückgegebene Element. Das ist effizient – O(1) für LinkedList und O(1) für ArrayList.

List<String> words = new ArrayList<>(List.of("hello", "world", "java"));
ListIterator<String> lit = words.listIterator();

while (lit.hasNext()) {
    String word = lit.next();
    lit.set(word.toUpperCase()); // replace each with uppercase
}

System.out.println(words); // [HELLO, WORLD, JAVA]

add() während der Iteration

add(element) fügt ein Element vor der nächsten Position ein. Das hinzugefügte Element wird von einem nachfolgenden Aufruf von next() nicht zurückgegeben – es befindet sich bereits „hinter“ dem Cursor.

List<Integer> numbers = new ArrayList<>(List.of(1, 2, 3));
ListIterator<Integer> lit = numbers.listIterator();

while (lit.hasNext()) {
    int n = lit.next();
    lit.add(n * 10); // insert n*10 after each element
}

System.out.println(numbers); // [1, 10, 2, 20, 3, 30]

Eine Liste direkt umkehren

Verwenden Sie ListIterator, um eine Liste in O(n) umzukehren, ohne eine neue Liste zu erzeugen.

static <T> void reverse(List<T> list) {
    ListIterator<T> front = list.listIterator(0);
    ListIterator<T> back  = list.listIterator(list.size());

    for (int i = 0, n = list.size() / 2; i < n; i++) {
        T frontVal = front.next();
        T backVal  = back.previous();
        front.set(backVal);
        back.set(frontVal);
    }
}

List<String> data = new ArrayList<>(List.of("a","b","c","d","e"));
reverse(data);
System.out.println(data); // [e, d, c, b, a]

nextIndex und previousIndex

nextIndex() gibt den Index des Elements zurück, das von next() zurückgegeben würde. previousIndex() gibt den Index des Elements zurück, das von previous() zurückgegeben würde.

List<String> list = List.of("X", "Y", "Z");
ListIterator<String> lit = list.listIterator();

System.out.println(lit.nextIndex());     // 0
System.out.println(lit.previousIndex()); // -1 (before start)

lit.next(); // consume X
System.out.println(lit.nextIndex());     // 1
System.out.println(lit.previousIndex()); // 0

ListIterator-Performance bei LinkedList

Der ListIterator von LinkedList erreicht O(1) für next/previous, da die Navigation durch das Folgen von Zeigern erfolgt. get(i) hat bei LinkedList die Komplexität O(n) – verwenden Sie ListIterator für eine effiziente Navigation.

import java.util.*;

LinkedList<Integer> list = new LinkedList<>();
for (int i = 0; i < 5; i++) list.add(i * 10);

// Efficient: O(n) total for traversal via ListIterator
ListIterator<Integer> lit = list.listIterator();
while (lit.hasNext()) {
    int val = lit.next();
    if (val == 20) lit.set(99); // O(1) update
}
System.out.println(list); // [0, 10, 99, 30, 40]

Palindromprüfung mit ListIterator

Ein elegantes Beispiel für bidirektionale Navigation: Prüfen, ob eine Liste ein Palindrom ist.

static <T> boolean isPalindrome(List<T> list) {
    ListIterator<T> front = list.listIterator(0);
    ListIterator<T> back  = list.listIterator(list.size());

    for (int i = 0, n = list.size() / 2; i < n; i++) {
        if (!front.next().equals(back.previous())) return false;
    }
    return true;
}

System.out.println(isPalindrome(List.of(1, 2, 3, 2, 1))); // true
System.out.println(isPalindrome(List.of(1, 2, 3, 4)));    // false

Vergleich von Iterator und ListIterator

Die wichtigsten Unterschiede:

  • Iterator: nur vorwärts, hasNext/next/remove
  • ListIterator: bidirektional, hasPrevious/previous, nextIndex/previousIndex, set/add
  • ListIterator nur für Listen (nicht für Set oder Queue)

Rückgängig/Wiederholen mit ListIterator

Ein cursorbasierter Texteditor, der ListIterator für eine effiziente Navigation von Zeichen beim Rückgängigmachen und Wiederholen verwendet.

import java.util.*;

class TextEditor {
    private final LinkedList<Character> chars = new LinkedList<>();
    private ListIterator<Character> cursor;

    TextEditor() { cursor = chars.listIterator(); }

    void type(char c) { cursor.add(c); } // insert before cursor

    void moveCursorLeft()  { if (cursor.hasPrevious()) cursor.previous(); }
    void moveCursorRight() { if (cursor.hasNext()) cursor.next(); }

    void backspace() {
        if (cursor.hasPrevious()) { cursor.previous(); cursor.remove(); }
    }

    String text() {
        StringBuilder sb = new StringBuilder();
        chars.forEach(sb::append);
        return sb.toString();
    }
}

TextEditor ed = new TextEditor();
ed.type('H'); ed.type('e'); ed.type('l'); ed.type('o');
ed.moveCursorLeft(); ed.moveCursorLeft();
ed.type('l');
System.out.println(ed.text()); // Hello

Wann Sie ListIterator verwenden sollten

Verwenden Sie ListIterator, wenn Sie Folgendes benötigen:

  • Navigation rückwärts durch eine Liste
  • Ersetzen von Elementen während der Navigation mit set()
  • Einfügen von Elementen während der Navigation mit add()
  • Positionsverfolgung über nextIndex()/previousIndex()

Schnelltest

Was bewirkt ListIterator.set()?

Zusammenfassung: ListIterator und bidirektionale Navigation

Die wichtigsten Erkenntnisse:

  • ListIterator erweitert Iterator um hasPrevious(), previous(), set() und add()
  • Erstellen Sie einen ListIterator an einer bestimmten Position mit listIterator(index)
  • set() ersetzt das letzte von next() oder previous() zurückgegebene Element
  • add() fügt ein Element vor der aktuellen Cursorposition ein
  • nextIndex() und previousIndex() liefern Informationen zur Position
  • Verwenden Sie den ListIterator von LinkedList für Navigation und Änderungen in O(1)

Häufig gestellte Fragen

Ist die Lektion „ListIterator und bidirektionales Durchlaufen“ kostenlos?

Ja — der vollständige Text von „ListIterator und bidirektionales Durchlaufen“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Java Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „ListIterator und bidirektionales Durchlaufen“?

Verwenden Sie ListIterator, um Listen vorwärts und rückwärts zu durchlaufen und Elemente während der Iteration zu ändern. Du übst Java Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Java Academy zu starten?

Keine Vorkenntnisse erforderlich. Java Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.

Wie lange dauert die Lektion „ListIterator und bidirektionales Durchlaufen“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Java Academy-Lektion Code schreiben und ausführen?

Ja. Jede Java Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Die Verträge von Iterable und Iterator
  2. Einen eigenen Iterator implementieren
  3. ListIterator und bidirektionales Durchlaufen
  4. Fail-Fast- vs. Fail-Safe-Iteratoren
← Zurück zu Java Academy