List.iterator în Java

iterator parcurge lista înainte; listIterator poate merge și înapoi, poate înlocui și insera elemente.

Sintaxă
Iterator<E> iterator()
ListIterator<E> listIterator()
ListIterator<E> listIterator(int index)

Ce face List.iterator

iterator() returnează un Iterator care trece prin elemente de la prima poziție la ultima, cu hasNext() și next(). Bucla for-each folosește exact acest iterator, în spate. Avantajul iteratorului scris explicit: poți șterge elementul curent cu remove() fără excepții.

listIterator() returnează un ListIterator, mai puternic: are și hasPrevious()/previous() (mers înapoi), nextIndex() (poziția următoare), set(x) (înlocuiește ultimul element returnat) și add(x) (inserează în poziția curentă). listIterator(index) pornește de la o poziție dată; listIterator(size()) pornește de la capăt, ca să mergi înapoi.

Parametri

Parametru Descriere
index Pentru listIterator(index): poziția primului element returnat de next().

Ce returnează

Un Iterator, respectiv un ListIterator, peste elementele listei.

Exemple

Exemplul 1: Ștergere sigură în timpul parcurgerii

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

public class Main {
    public static void main(String[] args) {
        List<String> emailuri = new ArrayList<>(List.of("ana@x.ro", "spam@reclame.ro", "mihai@x.ro", "oferta@reclame.ro"));
        Iterator<String> it = emailuri.iterator();
        while (it.hasNext()) {
            if (it.next().endsWith("@reclame.ro")) {
                it.remove();
            }
        }
        System.out.println(emailuri);
    }
}

Rezultat

[ana@x.ro, mihai@x.ro]

Exemplul 2: ListIterator: înlocuire și inserare

set înlocuiește elementul tocmai citit; add inserează după el, iar iteratorul trece peste elementul nou (de aceea pasul inserat nu primește număr). nextIndex() dă poziția reală din listă, deci după inserare numerotarea sare la 4.

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class Main {
    public static void main(String[] args) {
        List<String> pasi = new ArrayList<>(List.of("fierbe apa", "pune pastele", "servește"));
        ListIterator<String> it = pasi.listIterator();
        while (it.hasNext()) {
            int poz = it.nextIndex();
            String pas = it.next();
            it.set((poz + 1) + ". " + pas);
            if (pas.equals("pune pastele")) {
                it.add("așteaptă 10 minute");
            }
        }
        System.out.println(pasi);
    }
}

Rezultat

[1. fierbe apa, 2. pune pastele, așteaptă 10 minute, 4. servește]

Exemplul 3: Parcurgere de la coadă spre început

import java.util.List;
import java.util.ListIterator;

public class Main {
    public static void main(String[] args) {
        List<String> etaje = List.of("parter", "etajul 1", "etajul 2", "etajul 3");
        ListIterator<String> it = etaje.listIterator(etaje.size());
        while (it.hasPrevious()) {
            System.out.println("Liftul coboară la " + it.previous());
        }
    }
}

Rezultat

Liftul coboară la etajul 3
Liftul coboară la etajul 2
Liftul coboară la etajul 1
Liftul coboară la parter

Greșeli frecvente

  • Apelezi it.next() de două ori în aceeași iterație (o dată în if, o dată la afișare) și sari peste elemente. Salvează rezultatul într-o variabilă.
  • Ștergi cu lista.remove(x) în timp ce parcurgi cu iteratorul: apare ConcurrentModificationException. Folosește it.remove().
  • Apelezi it.set(...) sau it.remove() înainte de primul next(): aruncă IllegalStateException.

Comenzi înrudite

  • Iterator: Obiectul care parcurge o colecție element cu element: hasNext() întreabă dacă mai urmează ceva, next() îl dă pe următorul.
  • 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.
  • Collection.removeIf: Șterge din colecție toate elementele pentru care condiția dată este adevărată. Returnează true dacă s-a șters ceva.
  • List.spliterator: Returnează un Spliterator: un iterator care se poate împărți în bucăți, folosit de stream-uri pentru prelucrare în paralel.