Définition: fournit une méthode pour accéder à divers éléments dans un objet de conteneur sans exposer les détails internes de l'objet.
Type: modèle de comportement
Diagramme de classe:
Si vous souhaitez demander le mode le plus couramment utilisé en Java, la réponse n'est pas le mode Singleton, ni le mode d'usine, ni le mode stratégie, mais le mode itérateur. Jetons un coup d'œil à un morceau de code d'abord:
Public static void print (collection coll) {iterator it = coll.iterator (); while (it.hasnext ()) {String str = (string) it.next (); System.out.println (STR); }} La fonction de cette méthode consiste à imprimer une boucle de collecte de chaînes et le modèle d'itérateur est utilisé dans le modèle d'itérateur. Le langage Java a pleinement implémenté le modèle d'itérateur. L'itérateur traduit en chinois signifie itérateur. En ce qui concerne les itérateurs, tout d'abord, il est lié aux ensembles. Les ensembles sont également appelés agrégats, conteneurs, etc. Nous pouvons considérer les ensembles comme des conteneurs qui peuvent contenir des objets. Par exemple, la liste, le définition, la carte et même les tableaux peuvent être appelés ensembles. La fonction des itérateurs est de traverser les objets dans le conteneur un par un.
La structure du motif d'itérateur
Contauteur abstrait: Généralement, la méthode Iterator () est fournie, telle que l'interface de collecte, l'interface de liste, l'interface définie, etc. en Java.
Conteneur spécifique: il s'agit de la classe d'implémentation concrète des conteneurs abstraits, tels que la liste ordonnée de l'interface de liste pour implémenter ArrayList, la liste liée de l'interface de liste pour implémenter LinkList, la liste de hash de l'interface set pour implémenter HashSet, etc.
Résumé Iterator: Définissez la méthode requise pour traverser les éléments. D'une manière générale, il existe trois méthodes: Obtenez la première méthode () du premier élément, obtenez la méthode suivante () de l'élément suivant, déterminez si la méthode de traversée se termine Isdone () (ou Hasnext ()), supprimer () de l'objet actuel,
Implémentation de l'itérateur: implémente les méthodes définies dans l'interface Iterator pour compléter l'itération de la collection.
Donner un exemple
Étant donné que les réglementations du mode itérateur lui-même sont relativement lâches, la mise en œuvre spécifique est diversifiée. Donnons un seul exemple ici, et nous ne pouvons pas présenter les méthodes de mise en œuvre une par une. Par conséquent, avant de donner un exemple, énumérons les méthodes d'implémentation du modèle d'itérateur suivant.
1. Le rôle d'itérateur définit l'interface pour la traversée, mais ne spécifie pas qui contrôle l'itération. Dans l'application de la collection Java, le processus de traversée est contrôlé par le programme client, qui est appelé itérateur externe; Une autre méthode d'implémentation consiste à contrôler Iterator lui-même, qui est appelée itérateur interne. Les itérateurs externes sont flexibles et puissants que les itérateurs internes, et les itérateurs internes sont très faibles dans l'environnement régional Java.
2. Il n'y a aucune disposition pour qui implémentera l'algorithme de traversée en mode itérateur. Il semble naturel de mettre en œuvre dans le rôle de l'Iterator. Étant donné qu'il est pratique pour différents algorithmes de traversée à utiliser sur un conteneur, il est également pratique d'appliquer un algorithme de traversée à différents conteneurs. Mais cela détruit l'encapsulation du conteneur - le rôle de conteneur doit divulguer ses propres attributs privés, qui en Java signifie exposer ses propres attributs privés à d'autres classes.
Ensuite, mettons-le dans le rôle de conteneur pour l'implémenter. De cette façon, le rôle d'Iterator est remplacé pour stocker uniquement une fonction qui traverse l'emplacement actuel. Mais l'algorithme de traversée est étroitement lié à un récipient spécifique.
Dans l'application de la collection Java, le rôle d'itérateur spécifique fourni est la classe interne définie dans le rôle de conteneur. Cela protège l'emballage du conteneur. Mais en même temps, le conteneur fournit également une interface d'algorithme de traversée, et vous pouvez étendre votre propre itérateur.
Ok, jetons un coup d'œil à la mise en œuvre de la collection Iterator in Java.
// Le rôle d'itérateur, définit uniquement l'interface de traversée ITERATEUR D'Interface publique {Boolean Hasnext (); Objet suivant (); void retire ();} // rôle de conteneur, prenez la liste comme exemple ici. C'est juste une interface, donc elle ne sera pas répertoriée. Le rôle de conteneur spécifique est ArrayList et d'autres classes qui implémentent l'interface de liste. Pour mettre en évidence les points clés, nous nous référons au contenu lié à l'itérateur // Le rôle d'itérateur spécifique est dérivé sous la forme d'une classe interne. AbstractList existe pour extraire les parties communes de chaque rôle de conteneur spécifique. La classe abstraite publique AbstractList étend AbstractCollection implémente la liste {... // Il s'agit de la méthode d'usine responsable de la création de rôles d'Itérator spécifiques publics iterator () {return new ITR ();} // en tant que rôle d'itérateur spécifique de la classe interne ITR implémente iterator {int cursor = 0; int lastret = -1; int attendModCount = modCount; public boolean hasnext () {return Cursor! = size (); } objet public suivant () {checkForComodification (); essayez {objet suivant = get (curseur); lastret = cursor ++; retour ensuite; } catch (indexoutofboundSexception e) {checkForComodification (); lancer un nouveau nosuchementElementException (); }} public void dissovel () {if (lastret == -1) lancez new illégalStateException (); checkForComodification (); try {abstractList.this.remove (lastret); if (lastet <curseur) curseur--; lastret = -1; attendModCount = modCount; } catch (indexOutofBoundSexception e) {Throw New ConcurrentModificationException (); }} final void checkForComodification () {if (modCount! = attendModCount) New concurrentModificationException (); }}Quant à l'utilisation du mode itérateur. Comme indiqué dans l'introduction, le programme client doit d'abord obtenir le rôle de conteneur spécifique, puis obtenir le rôle d'itérateur spécifique via le rôle de conteneur spécifique. De cette façon, vous pouvez utiliser le rôle d'itérateur spécifique pour traverser le conteneur ...
Avantages et inconvénients du mode itérateur
Les avantages du mode itérateur sont:
La méthode de traversée a été simplifiée et il est encore assez gênant de traverser la collection d'objets. Pour les tableaux ou les listes ordonnées, nous pouvons toujours les obtenir via des curseurs, mais les utilisateurs doivent traverser les objets par eux-mêmes sur le principe qu'ils ont une compréhension claire de la collection. Cependant, pour la table de hachage, il est plus difficile de traverser l'utilisateur. Après avoir introduit la méthode Iterator, il est beaucoup plus facile pour les utilisateurs.
Il existe de nombreuses façons de traverser, comme pour les listes ordonnées, nous pouvons fournir à deux itérateurs un ordre positif et une traversée d'ordre inverse en fonction des besoins. Les utilisateurs n'ont qu'à obtenir l'itérateur que nous avons mis en œuvre pour traverser facilement la collection.
L'encapsulation est bonne et les utilisateurs n'ont qu'à faire traverser un itérateur, mais ils n'ont pas à se soucier des algorithmes de traversée.
Inconvénients du modèle d'itérateur:
Pour des traversées simples (telles que des tableaux ou des listes ordonnées), il est plus lourd d'utiliser des itérateurs, et tout le monde peut penser que, comme ArrayList, nous préférons utiliser pour des boucles et obtenir des méthodes pour traverser la collection.
Scénarios applicables pour le mode itérateur
Le modèle d'itérateur est symbiotique et mort avec la collection. D'une manière générale, tant que nous mettons en œuvre une collection, nous devons fournir l'itérateur de la collection en même temps, tout comme la collection, la liste, le set, la carte, etc. En Java, ces collections ont leurs propres itérateurs. Si nous voulons implémenter un tel nouveau conteneur, bien sûr, nous devons également introduire un modèle d'itérateur pour implémenter un itérateur pour notre conteneur.
Cependant, comme la relation entre les conteneurs et les itérateurs est trop proche, la plupart des langues fournissent des itérateurs lors de la mise en œuvre de conteneurs, et les conteneurs et les itérateurs fournis par ces langues peuvent répondre à nos besoins dans la plupart des cas. Par conséquent, il est relativement rare de pratiquer par nous-mêmes le modèle d'itérateur. Nous avons seulement besoin d'utiliser les conteneurs et les itérateurs existants dans la langue.