ListIterator e Percurso Bidirecional
Use ListIterator para percorrer listas para frente e para trás e modificar elementos durante a iteração.
ListIterator e Percurso Bidirecional é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Java Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Java Academy inclui 4 aulas no total.
ListIterator
ListIterator<T> estende Iterator<T> com travessia para trás, posicionamento baseado em índice e a capacidade de adicionar e substituir elementos durante a iteração.
API do ListIterator
Métodos adicionais além do iterador: 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:AComeçando em uma posição
Crie um ListIterator começando em um índice específico com 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 a iteração
set() substitui o último elemento retornado por next() ou previous(). Essa operação é eficiente: O(1) para LinkedList e O(1) para 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 a iteração
add(element) insere antes da próxima posição. O elemento adicionado não é retornado por uma chamada subsequente a next(): ele já está "atrás" do 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]Invertendo uma lista no próprio lugar
Use ListIterator para inverter uma lista em O(n), sem alocar uma nova 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() retorna o índice do elemento que seria retornado por next(). previousIndex() retorna o índice do elemento que seria retornado por 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()); // 0Desempenho do ListIterator em LinkedList
O ListIterator de LinkedList obtém next/previous em O(1), pois a travessia segue ponteiros. get(i) em LinkedList é O(n): use ListIterator para percorrer a estrutura com eficiência.
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ção de palíndromo com ListIterator
Um exemplo elegante de travessia bidirecional: verificar se uma lista é um palíndromo.
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))); // falseComparação entre Iterator e ListIterator
Principais diferenças:
- Iterator: apenas para frente, hasNext/next/remove
- ListIterator: bidirecional, hasPrevious/previous, nextIndex/previousIndex, set/add
- ListIterator apenas para listas, não para conjuntos ou filas
Desfazer/refazer com ListIterator
Um editor de texto baseado em cursor que usa ListIterator para navegar com eficiência entre os caracteres ao desfazer e refazer ações.
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 usar ListIterator
Use ListIterator quando precisar de:
- Travessia para trás em uma lista
- Substituição de elementos durante a travessia com set()
- Inserção de elementos durante a travessia com add()
- Acompanhamento da posição por meio de nextIndex()/previousIndex()
Verificação rápida
O que ListIterator.set() faz?
Recapitulação: ListIterator e travessia bidirecional
Principais aprendizados:
- ListIterator estende Iterator com hasPrevious(), previous(), set(), add()
- Crie um ListIterator em uma posição específica: listIterator(index)
- set() substitui o último elemento retornado por next() ou previous()
- add() insere antes da posição atual do cursor
- nextIndex() e previousIndex() fornecem informações sobre a posição
- Use o ListIterator de LinkedList para travessia e modificação em O(1)
Perguntas Frequentes
A aula “ListIterator e Percurso Bidirecional” é grátis?
Sim — o texto completo de “ListIterator e Percurso Bidirecional” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Java Academy, atualize para CoddyKit PRO. O curso de Java Academy inclui 4 aulas no total.
O que vou aprender em “ListIterator e Percurso Bidirecional”?
Use ListIterator para percorrer listas para frente e para trás e modificar elementos durante a iteração. Você pratica Java Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Java Academy?
Nenhuma experiência prévia é necessária. Java Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “ListIterator e Percurso Bidirecional”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Java Academy?
Sim. Cada aula de Java Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Contratos de Iterable e Iterator
- Implementação de um Iterator Personalizado
- ListIterator e Percurso Bidirecional
- Iterators Fail-Fast versus Fail-Safe