Les Itérateurs en Java¶
Objectif¶
Comprendre comment parcourir, lire et modifier les éléments d’une collection Java de manière sûre à l’aide des interfaces Iterator et ListIterator.
Définition générale¶
Un itérateur est un objet permettant de parcourir séquentiellement une collection.
Interface Iterator<E>¶
Interface ListIterator<E>¶
public interface ListIterator<E> extends Iterator<E> {
boolean hasPrevious();
E previous();
void add(E e);
void set(E e);
int nextIndex();
int previousIndex();
}
Pourquoi utiliser un itérateur ?¶
✅ Pour parcourir une collection sans connaître son type concret
✅ Pour supprimer proprement des éléments pendant l’itération
✅ Pour éviter les erreurs de ConcurrentModificationException
Exemple simple avec Iterator¶
List<String> noms = new ArrayList<>(List.of("Alice", "Bob", "Charles", "David"));
Iterator<String> it = noms.iterator();
while (it.hasNext()) {
String nom = it.next();
System.out.println(nom);
}
Sortie :
Supprimer des éléments pendant l’itération¶
List<String> noms = new ArrayList<>(List.of("Alice", "Bob", "Charles", "David"));
Iterator<String> it = noms.iterator();
while (it.hasNext()) {
String nom = it.next();
if (nom.startsWith("C")) {
it.remove(); // ✅ suppression sûre
}
}
System.out.println(noms); // [Alice, Bob, David]
⚠️ Si vous utilisiez noms.remove(nom) à la place, vous auriez une ConcurrentModificationException.
ListIterator : aller en avant et en arrière¶
List<String> noms = new ArrayList<>(List.of("Alice", "Bob", "Charles"));
ListIterator<String> it = noms.listIterator();
while (it.hasNext()) {
String nom = it.next();
if (nom.equals("Bob")) {
it.set("Robert"); // remplace l'élément courant
it.add("Brigitte"); // insère après l'élément courant
}
}
System.out.println(noms);
📤 Résultat :
Itérateurs avec Map¶
Pour parcourir une Map, on itère sur ses entrées clé→valeur :
Map<String,Integer> ages = Map.of("Alice", 22, "Bob", 30, "Charles", 27);
Iterator<Map.Entry<String,Integer>> it = ages.entrySet().iterator();
while (it.hasNext()) {
var entree = it.next();
System.out.println(entree.getKey() + " → " + entree.getValue());
}
Sortie :
Le for-each et les itérateurs¶
Le for-each est une forme simplifiée utilisant implicitement un Iterator.
remove() ici.
Itérateurs fail-fast vs fail-safe¶
| Type | Description | Exemple |
|---|---|---|
| Fail-fast | Détecte une modification concurrente et lève une ConcurrentModificationException. |
ArrayList, HashSet, HashMap |
| Fail-safe | Parcourt une copie instantanée et ne lève pas d’erreur. | CopyOnWriteArrayList, ConcurrentHashMap |
Cas d’utilisation typiques¶
| Objectif | Collection | Type d’itérateur |
|---|---|---|
| Supprimer des éléments pendant un parcours | ArrayList |
Iterator |
| Parcourir dans les deux sens | LinkedList |
ListIterator |
| Modifier la liste pendant le parcours | List |
ListIterator |
| Parcourir clé→valeur | Map |
Iterator<Map.Entry<K,V>> |
| Itération sûre en multithread | CopyOnWriteArrayList |
fail-safe |
Exemple complet : suppression avec Iterator¶
Énoncé¶
Créer une méthode qui supprime toutes les chaînes commençant par une lettre donnée.
Code¶
import java.util.*;
public class FiltreNoms {
public static void supprimerParInitiale(List<String> liste, char initiale) {
Iterator<String> it = liste.iterator();
while (it.hasNext()) {
String nom = it.next();
if (nom.charAt(0) == initiale) {
it.remove();
}
}
}
public static void main(String[] args) {
List<String> noms = new ArrayList<>(List.of("Alice","Bob","Charles","Caroline","David"));
supprimerParInitiale(noms, 'C');
System.out.println(noms);
}
}
Sortie :
Résumé¶
| Méthode | Rôle |
|---|---|
hasNext() |
Vérifie s’il reste un élément |
next() |
Renvoie l’élément suivant |
remove() |
Supprime le dernier élément lu |
hasPrevious() (ListIterator) |
Retour arrière possible |
previous() (ListIterator) |
Élément précédent |
add(E e) (ListIterator) |
Ajoute un élément à la position actuelle |
set(E e) (ListIterator) |
Remplace l’élément courant |