0Pricing
Java Academy · Aula

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:A

Começ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()); // 20

set() 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()); // 0

Desempenho 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)));    // false

Comparaçã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()); // Hello

Quando 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

  1. Contratos de Iterable e Iterator
  2. Implementação de um Iterator Personalizado
  3. ListIterator e Percurso Bidirecional
  4. Iterators Fail-Fast versus Fail-Safe
← Voltar para Java Academy