1. Contexte de la création des itérateurs
Vous connaissez déjà HashSet
. Si vous l'avez vraiment étudié, au-delà de la simple lecture d'une leçon, vous auriez dû poser cette question :
Comment afficher une liste de tous les éléments HashSet à l'écran ? Après tout, l'interface n'a pas get()
de set()
méthodes !
Et HashSet
n'est pas seul dans cette limitation. En plus de HashSet
, il existe de nombreuses autres collections qui n'autorisent pas la récupération des éléments par index, car les éléments n'ont pas d'ordre défini.
Au fil des ans, les programmeurs ont inventé de nombreuses structures de données complexes, telles que des graphiques et des arbres. Ou des listes de listes.
De nombreux conteneurs modifient l'ordre de leurs éléments lorsque de nouveaux éléments sont ajoutés ou que des éléments existants sont supprimés. Par exemple, une liste stocke les éléments dans un ordre particulier, et lorsqu'un nouvel élément est ajouté, il est presque toujours inséré au milieu de la liste.
Et nous obtenons également des situations où il y a un conteneur qui stocke des éléments mais pas dans un ordre fixe.
Supposons maintenant que nous voulions copier tous les éléments d'une telle collection dans un tableau ou une liste. Nous devons obtenir tous les éléments. Nous ne nous soucions pas de l'ordre dans lequel nous parcourons les éléments - l'important est de ne pas parcourir les mêmes éléments plus d'une fois. Comment fait-on cela?
2. Itérateur pour une collection
Les itérateurs ont été proposés comme solution au problème ci-dessus.
Un itérateur est un objet spécial associé à une collection, qui permet de parcourir tous les éléments de la collection sans en répéter aucun.
Vous pouvez utiliser le code suivant pour obtenir un itérateur pour n'importe quelle collection :
Iterator<Type> it = name.iterator();
Où name
est le nom de la variable de collection, Type
est le type des éléments de la collection, iterator()
est l'une des méthodes de la collection et it
est le nom de la variable d'itérateur.
Un objet itérateur a 3 méthodes :
Méthode | Description |
---|---|
|
Renvoie l'élément suivant de la collection |
|
Vérifie s'il y a des éléments qui n'ont pas encore été parcourus |
|
Supprime l'élément courant de la collection |
nextInt)
Ces méthodes sont quelque peu similaires aux méthodes et à la classe Scanner hasNextInt()
.
La next()
méthode renvoie l'élément suivant de la collection à partir de laquelle nous avons obtenu l'itérateur.
La hasNext()
méthode vérifie si la collection contient des éléments supplémentaires que l'itérateur n'a pas encore renvoyés.
Voici comment afficher tous les éléments d'un HashSet
:
Code | Remarques |
---|---|
|
Créez un HashSet objet qui stocke String des éléments. Nous ajoutons des salutations dans différentes langues à la set variable. Obtenez un objet itérateur pour l' set ensemble. Tant qu'il reste des éléments Obtenir l'élément suivant Afficher l'élément à l'écran |
3. For-each
boucle
Le principal inconvénient d'un itérateur est que votre code devient plus lourd que d'utiliser une for
boucle.
Pour comparer, affichons une liste à l'aide d'une for
boucle et également à l'aide d'un itérateur :
Itérateur | pour la boucle |
---|---|
|
|
Oui, c'est bien mieux de parcourir les éléments d'un en ArrayList
utilisant une boucle — tout s'avère plus court.
Mais les créateurs de Java ont de nouveau décidé de nous verser du sucre. Heureusement pour nous, c'était du sucre syntaxique .
Ils ont donné à Java un nouveau type de boucle et l'ont appelé une for-each
boucle. Voici à quoi ça ressemble en général:
for(Type name:collection)
Où collection
est le nom de la variable de collection, Type
est le type des éléments de la collection et name
est le nom d'une variable qui prend la valeur suivante de la collection à chaque itération de la boucle.
Ce type de boucle parcourt tous les éléments d'une collection à l'aide d'un itérateur implicite. Voici comment cela fonctionne réellement :
Boucle pour chaque | Ce que le compilateur voit : Boucle avec un itérateur |
---|---|
|
|
Lorsque le compilateur rencontre une for-each
boucle dans votre code, il la remplace simplement par le code de droite : il ajoute un appel pour obtenir un itérateur avec tout autre appel de méthode manquant.
Les programmeurs adorent la for-each
boucle et l'utilisent presque toujours lorsqu'ils doivent itérer sur tous les éléments d'une collection.
Même l'itération sur une ArrayList
liste à l'aide d'une for-each
boucle semble plus courte :
Boucle pour chaque | pour la boucle |
---|---|
|
|
4. Supprimer un élément dans une for-each
boucle
La for-each
boucle a un inconvénient : elle ne peut pas supprimer correctement les éléments. Si vous écrivez un code comme celui-ci, vous obtiendrez une erreur.
Code | Note |
---|---|
|
L'opération de suppression générera une erreur ! |
C'est un code très agréable et compréhensible, mais cela ne fonctionnera pas.
Vous ne pouvez pas modifier une collection pendant que vous la parcourez avec un itérateur.
Il existe trois façons de contourner cette limitation.
1. Utilisez un autre type de boucle
When traversing an ArrayList collection
, vous pouvez utiliser une boucle ordinaire avec une i
variable compteur.
Code |
---|
|
Cependant, cette option n'est pas adaptée aux collections HashSet
etHashMap
2. Utilisez un itérateur explicite
Vous pouvez utiliser un itérateur explicitement et appeler sa remove()
méthode.
Version qui fonctionne | Version qui ne fonctionne pas |
---|---|
|
|
Notez que nous appelons la remove()
méthode sur l'objet itérateur ! L'itérateur est conscient que l'élément a été supprimé et peut gérer la situation correctement.
3. Utilisez une copie de la collection
Vous pouvez également créer une copie de la collection, puis utiliser la copie dans une for-each
boucle et supprimer des éléments de la collection d'origine.
Code | Note |
---|---|
|
Créer une copie d'une collection est super facile La boucle utilise l'itérateur pour la copie de la collection. Les éléments sont supprimés de la list collection. |
La collection est copiée assez rapidement, car les éléments eux-mêmes ne sont pas dupliqués. Au lieu de cela, la nouvelle collection stocke les références aux éléments qui existent déjà dans l'ancienne collection.
GO TO FULL VERSION