Contratos de Iterable e Iterator
Compreenda as interfaces Iterable e Iterator e como os laços for-each funcionam internamente.
Contratos de Iterable e Iterator é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 1 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.
Iterable e Iterator
Iterable<T> e Iterator<T> são as interfaces que dão suporte ao laço de iteração de Java. Compreendê-las permite criar suas próprias estruturas de dados compatíveis com laços.
A interface Iterable
Iterable<T> tem um método: iterator(), que retorna um Iterator<T>. Qualquer classe que implemente Iterable pode ser usada em um laço de iteração.
// java.lang.Iterable<T>
interface Iterable<T> {
Iterator<T> iterator();
// default: forEach, spliterator (Java 8+)
}
// Any class implementing Iterable<T> works in for-each:
class Range implements Iterable<Integer> {
private final int start, end;
Range(int start, int end) { this.start = start; this.end = end; }
public Iterator<Integer> iterator() {
return new RangeIterator(); // defined separately
}
}A interface Iterator
Iterator<T> tem três métodos: hasNext(), next() e o método opcional remove().
// java.util.Iterator<T>
interface Iterator<T> {
boolean hasNext(); // true if more elements
T next(); // returns next element, advances cursor
default void remove() { throw new UnsupportedOperationException(); }
}
// How for-each desugars internally:
// for (T item : iterable) { use(item); }
// becomes:
Iterator<T> it = iterable.iterator();
while (it.hasNext()) {
T item = it.next();
// use(item)
}Expansão do laço de iteração
O laço de iteração é um açúcar sintático sobre o padrão Iterable/Iterator. Compreender isso ajuda você a escrever Iterable personalizados corretamente.
List<String> names = List.of("Alice", "Bob", "Charlie");
// For-each (readable way)
for (String name : names) {
System.out.println(name);
}
// Equivalent explicit form
Iterator<String> it = names.iterator();
while (it.hasNext()) {
String name = it.next();
System.out.println(name);
}Estado do cursor de Iterator
Um Iterator mantém um cursor — uma posição na sequência. Chamar next() move o cursor para a frente. Depois de esgotado, o iterador não pode ser reiniciado.
List<Integer> nums = List.of(1, 2, 3);
Iterator<Integer> it = nums.iterator();
System.out.println(it.hasNext()); // true
System.out.println(it.next()); // 1
System.out.println(it.next()); // 2
System.out.println(it.next()); // 3
System.out.println(it.hasNext()); // false
try {
it.next(); // NoSuchElementException
} catch (java.util.NoSuchElementException e) {
System.out.println("No more elements!");
}ConcurrentModificationException
Modificar uma coleção enquanto se itera com um iterador explícito (fora de Iterator.remove()) lança ConcurrentModificationException.
List<String> list = new ArrayList<>(List.of("a", "b", "c", "d"));
// BAD: modifying collection during for-each
try {
for (String s : list) {
if ("b".equals(s)) list.remove(s); // ConcurrentModificationException!
}
} catch (java.util.ConcurrentModificationException e) {
System.out.println("Cannot modify during iteration!");
}
// GOOD: use Iterator.remove()
Iterator<String> it = list.iterator();
while (it.hasNext()) {
if ("b".equals(it.next())) it.remove(); // safe
}
System.out.println(list); // [a, c, d]Vários iteradores
Cada chamada a iterator() retorna um iterador novo e independente. Vários iteradores podem estar ativos simultaneamente na mesma coleção.
List<Integer> nums = List.of(1, 2, 3);
Iterator<Integer> a = nums.iterator();
Iterator<Integer> b = nums.iterator();
System.out.println(a.next()); // 1
System.out.println(b.next()); // 1 (independent cursor)
System.out.println(a.next()); // 2
System.out.println(b.next()); // 2Iterable ou Iterator
Distinção principal:
- Iterable: uma fonte que pode produzir iteradores — pode ser percorrida várias vezes
- Iterator: um cursor sobre uma sequência — de uso único e com estado
// Iterable: reusable
List<String> list = List.of("x", "y");
for (String s : list) {} // OK
for (String s : list) {} // OK again — new iterator each time
// Iterator: single-use
Iterator<String> it = list.iterator();
while (it.hasNext()) it.next();
// for (String s : it) {} // compile error — Iterator is not Iterable!Prática: Iterable personalizado para linhas de arquivo
Um leitor de arquivos que implementa Iterable para permitir percorrer suas linhas com um laço de iteração.
import java.io.*;
import java.util.*;
class FileLines implements Iterable<String>, Closeable {
private final BufferedReader reader;
FileLines(String path) throws IOException {
this.reader = new BufferedReader(new FileReader(path));
}
public Iterator<String> iterator() {
return new Iterator<>() {
private String nextLine = readNext();
private String readNext() {
try { return reader.readLine(); }
catch (IOException e) { return null; }
}
public boolean hasNext() { return nextLine != null; }
public String next() {
String curr = nextLine;
nextLine = readNext();
return curr;
}
};
}
public void close() throws IOException { reader.close(); }
}Método padrão forEach
Java 8 adicionou um método padrão forEach(Consumer) a Iterable. Essa é uma alternativa conveniente à escrita de laços explícitos.
List<String> cities = List.of("New York", "London", "Tokyo");
// for-each loop
for (String city : cities) System.out.println(city);
// forEach with lambda
cities.forEach(city -> System.out.println(city));
// forEach with method reference (most concise)
cities.forEach(System.out::println);
// For transforming: use stream
cities.stream()
.map(String::toUpperCase)
.forEach(System.out::println);Padrão Iterator na prática
Resumo de quando implementar Iterable/Iterator:
- Estruturas de dados personalizadas (árvore, grafo, lista encadeada)
- Sequências preguiçosas que geram elementos sob demanda
- Sequências baseadas em recursos (linhas de arquivo, cursor de banco de dados, fila de mensagens)
Verificação rápida
Qual exceção é lançada quando você modifica uma coleção enquanto a percorre com um laço de iteração?
Recapitulação: os contratos de Iterable e Iterator
Principais conclusões:
- Iterable
tem um método: iterator() — habilita o suporte a laços de iteração - Iterator
tem hasNext(), next() e remove() opcional - O laço de iteração é um açúcar sintático sobre o padrão Iterable/Iterator
- Chame iterator() várias vezes para obter cursores novos e independentes
- Nunca modifique uma coleção durante um laço de iteração — use Iterator.remove() em vez disso
- Implemente Iterable em estruturas de dados personalizadas para permitir laços de iteração
Perguntas Frequentes
A aula “Contratos de Iterable e Iterator” é grátis?
Sim — o texto completo de “Contratos de Iterable e Iterator” é 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 “Contratos de Iterable e Iterator”?
Compreenda as interfaces Iterable e Iterator e como os laços for-each funcionam internamente. 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 1 de 4.
Quanto tempo leva a aula “Contratos de Iterable e Iterator”?
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