« Salut Amigo ! »

« Salut, Élie ! »

"Aujourd'hui, je veux vous parler des itérateurs."

"Les itérateurs ont été inventés pratiquement en même temps que les collections. Le but principal des collections est de stocker des éléments, et le but principal d'un itérateur est de récupérer ces éléments un par un."

"Qu'y a-t-il de si difficile à obtenir un ensemble d'éléments ?"

"Premièrement, les éléments de certaines collections, comme Set, n'ont pas d'ordre établi et/ou l'ordre change constamment."

"Deuxièmement, certaines structures de données peuvent stocker des objets de manière très complexe : dans différents groupes, listes, etc. En d'autres termes, distribuer tous les éléments dans l'ordre serait une tâche non triviale."

"Troisièmement, les collections ont tendance à changer. Supposons que vous décidiez d'afficher tout le contenu d'une collection, mais qu'en plein milieu de la sortie, la JVM passe à un autre thread qui remplace la moitié des éléments de la collection. Ainsi, au lieu de la sortie, vous obtenez qui sait quoi."

"Hmm..."

"Mais ! C'est précisément le genre de problèmes qu'un itérateur peut résoudre. Un itérateur est un objet spécial au sein d'une collection qui, d'une part, a accès à toutes ses données privées et connaît sa structure interne, et d'autre part , implémente l'interface publique Iterator, qui permet à chacun de savoir comment l'utiliser. "

"Certains itérateurs ont un tableau interne dans lequel tous les éléments de la collection sont copiés lors de la création de l'itérateur. Cela garantit que toute modification ultérieure de la collection n'affectera pas le nombre ou l'ordre des éléments."

"Je pense que vous avez rencontré cela lorsque vous travaillez avec for each . Vous ne pouvez pas parcourir simultanément une collection et en supprimer des éléments. Tout cela est précisément dû au fonctionnement d'un itérateur."

"Dans les nouvelles collections ajoutées à la bibliothèque de concurrence, l'itérateur est retravaillé pour éliminer ce problème."

"Laissez-moi vous rappeler comment fonctionne un itérateur."

"Java a une interface Iterator spéciale. Voici ses méthodes :"

Méthodes de l'interface Iterator<E> Description
boolean hasNext() Vérifie s'il y a d'autres éléments
E next() Retourne l'élément courant et passe au suivant.
void remove() Supprime l'élément courant

"Un itérateur vous permet d'obtenir successivement tous les éléments d'une collection. Il est plus logique de penser à un itérateur comme quelque chose comme un InputStream - il a toutes les données, mais sa tâche est de les sortir séquentiellement."

"La   méthode next () renvoie l'élément suivant dans la collection."

"La méthode hasNext () est utilisée pour vérifier s'il y a d'autres éléments."

"Et remove () supprime l'élément actuel."

"Des questions?"

"Pourquoi les méthodes ont-elles des noms aussi étranges ? Pourquoi pas isEmpty() et getNextElement() ?"

"Est-ce que ça n'aurait pas plus de sens ?"

"Cela aurait plus de sens, mais les noms viennent du langage C++, où les itérateurs sont apparus plus tôt."

"Je vois. Continuons."

"En plus d'un itérateur, il existe également l'interface Iterable, qui doit être implémentée par toutes les collections prenant en charge les itérateurs. Elle possède une seule méthode :"

Méthodes de l'interface Iterable<T> Description
Iterator<T>iterator() Renvoie un objet itérateur

"Vous pouvez utiliser cette méthode sur n'importe quelle collection pour qu'un objet itérateur parcoure ses éléments. Passons en revue tous les éléments d'un TreeSet :"

Exemple
TreeSet<String> set = new TreeSet<String>();
Iterator<String> iterator = set.iterator();

while (iterator.hasNext())
{
 String item = iterator.next();
 System.out.println(item);
}

"Utiliser un itérateur comme celui-ci n'est pas très pratique - il y a trop de code superflu et évident. La situation est devenue plus simple lorsque la boucle for-each est apparue en Java."

"Maintenant, ce code est beaucoup plus compact et lisible :"

Avant Après
TreeSet<String> set = new TreeSet<String>();
Iterator<String> iterator = set.iterator();

while (iterator.hasNext())
{
 String item = iterator.next();
 System.out.println(item);
}
TreeSet<String> set = new TreeSet<String>();

for(String item : set)
{
 System.out.println(item);
}

"C'est le même code ! L'itérateur est utilisé dans les deux cas."

"C'est juste que son utilisation est cachée dans la boucle for-each . Notez que le code de droite n'a pas du tout de texte rouge . L'utilisation de l'itérateur est complètement cachée."

"Une boucle for-each doit être utilisée pour tous les objets prenant en charge les itérateurs. En d'autres termes, vous pouvez écrire votre propre classe, y ajouter la méthode iterator () et utiliser ses objets dans une construction for-each ."

"Wow ! Bien sûr, je ne suis pas impatient d'écrire mes propres collections et itérateurs, mais la perspective est toujours tentante. Je vais en prendre note."

De plus, il existe un autre type d'itérateur populaire qui possède même sa propre interface. Je parle d'un itérateur pour les listes, c'est-à-dire ListIterator .

"Quelle que soit leur implémentation, les listes conservent l'ordre des éléments, ce qui facilite un peu plus leur utilisation via un itérateur."

"Voici les méthodes de l' interface ListIterator <E> :"

Méthode Description
boolean hasNext() Vérifie s'il y a d'autres éléments devant.
E next() Renvoie l'élément suivant.
int nextIndex() Renvoie l'indice de l'élément suivant
void set(E e) Change la valeur de l'élément courant
boolean hasPrevious() Vérifie s'il y a des éléments derrière.
E previous() Renvoie l'élément précédent
int previousIndex() Renvoie l'indice de l'élément précédent
void remove() Supprime l'élément courant
void add(E e) Ajoute un élément à la fin de la liste.

"En d'autres termes, ici, nous pouvons avancer et reculer. Et il y a quelques autres petites fonctionnalités."

"Eh bien, c'est quelque chose d'intéressant. Où est-il utilisé?"

"Supposons que vous vouliez vous déplacer dans une liste chaînée. L'opération get sera plutôt lente, mais l'opération next() sera très rapide."

"Hmm. Tu m'as convaincu. Je vais garder ça à l'esprit."

« Merci, Élie ! »