ListIterator e attraversamento bidirezionale
Utilizzi ListIterator per attraversare le liste in avanti e all'indietro e modificare gli elementi durante l'iterazione.
ListIterator e attraversamento bidirezionale è una lezione Java Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Java Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Java Academy include 4 lezioni in totale.
ListIterator
ListIterator<T> estende Iterator<T> con l'attraversamento all'indietro, il posizionamento basato sugli indici e la possibilità di aggiungere e sostituire elementi durante l'iterazione.
API di ListIterator
Metodi aggiuntivi rispetto a 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:APartire da una posizione
Crei un ListIterator a partire da un indice specifico con listIterator(index).
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() durante l'iterazione
set() sostituisce l'ultimo elemento restituito da next() o previous(). Questa operazione è efficiente: O(1) per LinkedList e O(1) per 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() durante l'iterazione
add(element) inserisce l'elemento prima della posizione successiva. L'elemento aggiunto non viene restituito da una successiva chiamata a next(): si trova già "dietro" il cursore.
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]Invertire una lista sul posto
Utilizzare ListIterator per invertire una lista in O(n) senza allocare una nuova lista.
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 e previousIndex
nextIndex() restituisce l'indice dell'elemento che verrebbe restituito da next(). previousIndex() restituisce l'indice dell'elemento che verrebbe restituito da previous().
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()); // 0Prestazioni di ListIterator con LinkedList
Il ListIterator di LinkedList raggiunge O(1) per next/previous perché l'attraversamento segue i puntatori. get(i) su LinkedList è O(n): utilizzi ListIterator per attraversare la lista in modo efficiente.
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]Verifica di un palindromo con ListIterator
Un elegante esempio di attraversamento bidirezionale: verificare se una lista è un palindromo.
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))); // falseConfronto tra Iterator e ListIterator
Differenze principali:
- Iterator: solo in avanti, hasNext/next/remove
- ListIterator: bidirezionale, hasPrevious/previous, nextIndex/previousIndex, set/add
- ListIterator solo per le Lists (non per Set o Queue)
Undo/Redo con ListIterator
Un editor di testo basato su un cursore che utilizza ListIterator per una navigazione efficiente dei caratteri durante le operazioni di undo/redo.
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()); // HelloQuando utilizzare ListIterator
Utilizzi ListIterator quando ha bisogno di:
- Attraversare una lista all'indietro
- Sostituire elementi durante l'attraversamento con set()
- Inserire elementi durante l'attraversamento con add()
- Tenere traccia della posizione tramite nextIndex()/previousIndex()
Verifica rapida
Che cosa fa ListIterator.set()?
Riepilogo: ListIterator e attraversamento bidirezionale
Punti chiave:
- ListIterator estende Iterator con hasPrevious(), previous(), set(), add()
- Crei un ListIterator in una posizione specifica con listIterator(index)
- set() sostituisce l'ultimo elemento restituito da next() o previous()
- add() inserisce l'elemento prima della posizione corrente del cursore
- nextIndex() e previousIndex() forniscono informazioni sulla posizione
- Utilizzi ListIterator con LinkedList per un attraversamento e una modifica in O(1)
Domande Frequenti
La lezione «ListIterator e attraversamento bidirezionale» è gratuita?
Sì — il testo completo di «ListIterator e attraversamento bidirezionale» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Java Academy, passa a CoddyKit PRO. Il corso Java Academy include 4 lezioni in totale.
Cosa imparerò in «ListIterator e attraversamento bidirezionale»?
Utilizzi ListIterator per attraversare le liste in avanti e all'indietro e modificare gli elementi durante l'iterazione. Eserciti Java Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Java Academy?
Non è richiesta alcuna esperienza precedente. Java Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.
Quanto tempo richiede la lezione «ListIterator e attraversamento bidirezionale»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Java Academy?
Sì. Ogni lezione Java Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- I contratti di Iterable e Iterator
- Implementazione di un Iterator personalizzato
- ListIterator e attraversamento bidirezionale
- Iterator fail-fast e fail-safe