Iterator în Java

Obiectul care parcurge o colecție element cu element: hasNext() întreabă dacă mai urmează ceva, next() îl dă pe următorul.

Sintaxă
Iterator<E> it = colectie.iterator();

boolean hasNext()
E next()

Ce face Iterator

Un Iterator este un „cursor” peste o colecție. Îl obții cu colectie.iterator(). hasNext() returnează true dacă mai există elemente, iar next() returnează următorul element și mută cursorul mai departe.

Bucla for-each folosește în spate exact un iterator. Îl scrii explicit când ai nevoie de mai mult control: să ștergi elemente în timpul parcurgerii (remove()), să parcurgi două colecții în paralel sau să te oprești și să continui mai târziu.

Dacă apelezi next() când nu mai sunt elemente, apare NoSuchElementException. Un iterator merge doar înainte și se folosește o singură dată; pentru încă o parcurgere ceri unul nou.

Ce returnează

hasNext(): boolean. next(): următorul element.

Exemple

Exemplul 1: Parcurgere cu hasNext și next

import java.util.Iterator;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> elevi = List.of("Ana", "Mihai", "Ioana");
        Iterator<String> it = elevi.iterator();
        while (it.hasNext()) {
            String e = it.next();
            System.out.println("Strig catalogul: " + e);
        }
        System.out.println("Mai sunt? " + it.hasNext());
    }
}

Rezultat

Strig catalogul: Ana
Strig catalogul: Mihai
Strig catalogul: Ioana
Mai sunt? false

Exemplul 2: Două colecții parcurse în paralel

Cu doi iteratori poți asocia elementele de pe aceleași poziții din două colecții.

import java.util.Iterator;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        Iterator<String> nume = List.of("Ana", "Radu", "Elena").iterator();
        Iterator<Integer> note = List.of(9, 7, 10).iterator();
        while (nume.hasNext() && note.hasNext()) {
            System.out.println(nume.next() + ": " + note.next());
        }
    }
}

Rezultat

Ana: 9
Radu: 7
Elena: 10

Exemplul 3: next() după ultimul element

import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

public class Main {
    public static void main(String[] args) {
        Iterator<String> it = List.of("Iași").iterator();
        System.out.println(it.next());
        try {
            it.next();
        } catch (NoSuchElementException e) {
            System.out.println("Eroare: NoSuchElementException, nu mai sunt elemente");
        }
    }
}

Rezultat

Iași
Eroare: NoSuchElementException, nu mai sunt elemente

Greșeli frecvente

  • Apelezi next() de două ori în aceeași iterație (o dată în if, o dată la afișare). Sari peste elemente; salvează rezultatul într-o variabilă.
  • Folosești tipul brut Iterator it = lista.iterator();. Scrie Iterator<String>, altfel compilatorul avertizează.
  • Modifici colecția prin lista.add/lista.remove în timpul parcurgerii. Următorul next() aruncă ConcurrentModificationException.

Comenzi înrudite

  • Iterator.remove: Șterge din colecție elementul returnat ultima dată de next(). Este felul sigur de a șterge în timpul parcurgerii.
  • Iterable: Interfața care permite bucla for-each: orice obiect Iterable poate fi parcurs cu for (T x : obiect) și cu forEach.
  • List.iterator: iterator parcurge lista înainte; listIterator poate merge și înapoi, poate înlocui și insera elemente.
  • List.spliterator: Returnează un Spliterator: un iterator care se poate împărți în bucăți, folosit de stream-uri pentru prelucrare în paralel.
  • Collection: Interfața de bază pentru liste, mulțimi și cozi: metodele comune add, remove, contains, size și parcurgerea cu for-each.