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:AAn 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()); // 20set() 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()); // 0ListIterator-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))); // falseVergleich 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()); // HelloWann 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
- Die Verträge von Iterable und Iterator
- Einen eigenen Iterator implementieren
- ListIterator und bidirektionales Durchlaufen
- Fail-Fast- vs. Fail-Safe-Iteratoren