Mécanisme de Parcours Séquentiel
L'itérateur constitue l'approche standardisée pour extraire les éléments d'une collection sans exposer sa structure interne. La méthode classique utilise une boucle while couplée à un objet explicite :
List<String> references = new ArrayList<>();
references.add("donnee_A");
references.add("donnee_B");
references.add("donnee_C");
Iterator<String> parcours = references.iterator();
while (parcours.hasNext()) {
System.out.println(parcours.next());
}
Une variante structurelle privilégie la boucle for standard :
for (Iterator<String> curseur = references.iterator(); curseur.hasNext(); ) {
System.out.println(curseur.next());
}
Implications sur la Gestion Mémoire
Dans la construction for, la référence curseur possède une portée restreinte au bloc d'itération. Dès la sortie de la boucle, l'objet devient éligible au garbage collection, libérant immédiatement la mémoire occupée par l'instance d'itération. La version while déclare la variable en amont, maintenant une référence active dans la scope parente même après l'épuisement des éléments, ce qui peut générer une rétention inutile dans les environnements à forte charge ou à longue durée de vie.
Contrat Méthodologique de l'Interface
boolean hasNext(): Vérifie la présence d'un élément non consommé dans la séquence.E next(): Avance le pointeur interne et retourne l'objet suivant.void remove(): Supprime le dernier élément renvoyé parnext()sans invalider la structure sous-jacente.
Découplage Architecturel avec les Collections
Les implémentations de collections (tableaux contigus, listes chaînées, arbres, tables de hachage) reposent sur des mécanismes d'accès radicalement différents. Uniformiser l'extraction via une méthode unique directement dans l'interface de la collection serait complexe et inefficace. L'itérateur agit donc comme une abstraction portable, encapsulant l'algorithme de navigation propre à chaque structure.
La conception sous forme de classe interne (ou privée) est délibérée : elle autorise un accès direct aux champs privés de la collection parente (size, array, nodes), tout en masquant les détails d'implémentation au consommateur. Une classe externe obligerait à exposer des méthodes publiques de lecture ou à répliquer l'état de la collection, rompant l'encapsulation.
Implémentation Interne et Vérification de Cohérence
Dans l'API Java standard, la classe AbstractList délègue la création d'un itérateur à une sous-classe privée nommée Itr. Cette classe implémente directement le contrat Iterator<E> et gère un mécanisme fail-fast via la comparaison de compteurs de modification.
private final class SequenceIterator implements Iterator<E> {
private int positionActuelle = 0;
private int dernierElementRenvoye = -1;
private int compteurModificationsPrevu = versionStructurelle;
public boolean hasNext() {
return positionActuelle < obtenirTaille();
}
public E next() {
validerCohérence();
try {
E resultat = obtenirElement(positionActuelle);
dernierElementRenvoye = positionActuelle;
positionActuelle++;
return resultat;
} catch (IndexOutOfBoundsException ex) {
validerCohérence();
throw new NoSuchElementException();
}
}
public void remove() {
if (dernierElementRenvoye == -1) {
throw new IllegalStateException();
}
validerCohérence();
try {
CollectionParent.this.supprimer(dernierElementRenvoye);
if (dernierElementRenvoye < positionActuelle) {
positionActuelle--;
}
dernierElementRenvoye = -1;
compteurModificationsPrevu = versionStructurelle;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
private void validerCohérence() {
if (versionStructurelle != compteurModificationsPrevu) {
throw new ConcurrentModificationException();
}
}
}
Le champ versionStructurelle (éqiuvalent à modCount) est incrémenté par la collection à chaque ajout ou suppression. L'itérateur capture sa valeur initiale et la compare systématiquement lors des appels à next() et remove(). Toute divergence déclenche une ConcurrentModificationException, garantissant qu'une modification externe ou concurrente ne corrompe pas le parcours en cours. La suppression interne met à jour les indices et synchronise les compteurs pour maintenir l'état valide de l'itérateur.