Préface
La raison de l'introduction améliorée pour les boucles: dans les versions précédentes de JDK5, il est plus difficile de traverser des éléments dans un tableau ou une collection et un itérateur de la longueur ou de la collection de réseau.
Une nouvelle syntaxe est définie dans JDK5 - améliorée pour les boucles pour simplifier ces opérations. Enhanced pour les boucles ne peuvent être utilisés que sur des tableaux ou des collections qui implémentent les interfaces itératives.
Format de syntaxe:
pour (variable de type variable: tableau ou collection qui doit être itérée) {
}
En Java, la traversée des collections et des tableaux a généralement les trois formes suivantes:
pour (int i = 0; i <list.size (); i ++) {System.out.print (list.get (i) + ",");} iterator iterator = list.iterator (); while (iterator.hasnext ()) {System.out.print (iterator.next () + ",");} pour (entier i: list) {System.out.print (i + ",");} Le premier est ordinaire pour la traversée de boucle, la seconde consiste à utiliser des itérateurs pour la traversée, et le troisième est généralement appelé amélioré pour la boucle (pour chacun).
Principe de mise en œuvre
On peut voir que la troisième forme est le sucre syntaxique fourni par Java. Ici, nous analysons comment cette boucle améliorée pour la boucle est mise en œuvre dans la couche sous-jacente.
Nous décompilons le code suivant:
pour (entier i: list) {System.out.println (i);}Après la décompilation:
Integer i; pour (iterator iterator = list.iterator (); iterator.hasnext (); System.out.println (i)) {i = (Integer) iterator.next (); } Le code décompilé est en fait assez compliqué, alors décomposons-le dans l'ordre d'exécution:
Entier i; définit une variable temporaire i
Iterator iterator = list.iterator (); Obtenez l'itérateur de la liste
iterator.hasnext (); Détermine s'il y a des éléments non torrides dans l'itérateur
i = (entier) iterator.next (); Obtenez le premier élément non trahisé et affectez-le à la variable temporaire I
System.out.println (i) produit la valeur de la variable temporaire i
Cela cycle jusqu'à ce que tous les éléments de la liste soient traversés.
Grâce à la décompilation, nous voyons que la couche sous-jacente de boucles améliorées pour les boucles en Java est en fait implémentée via le modèle d'itérateur.
La fosse de l'amélioration de la boucle pour
On dit que c'est une fosse dans l'amélioration de la boucle, mais c'est en fait principalement parce que certaines personnes peuvent entrer dans la fosse du principe de mise en œuvre de l'amélioration de la boucle.
Étant donné que l'amélioration de la boucle est mise en œuvre via un itérateur, elle doit avoir les caractéristiques d'un itérateur.
Il y a un mécanisme de défaillance à Java. Lorsque vous utilisez un itérateur pour traverser des éléments, vous devez être prudent lors de la suppression de la collection. Si vous l'utilisez mal, la conception concurrente de l'Exception peut se produire. Il s'agit d'une exception d'exécution et ne se produira pas pendant la période de compilation. Il ne fera exploser que lorsque le programme sera réellement en cours d'exécution.
Comme dans le code suivant:
pour (étudiant Stu: étudiants) {if (stu.getId () == 2) Students.Remove (Stu); }Une exception en conception concurrente-motification sera lancée.
Iterator fonctionne dans un thread séparé et a un verrou de mutex. Une fois l'itérateur créé, une table d'index unique pointant vers l'objet d'origine. Lorsque le nombre d'objets d'origine change, le contenu de ce tableau d'index ne changera pas de manière synchrone, donc lorsque le pointeur d'index se déplace vers l'arrière, l'objet à itérater ne peut pas être trouvé, donc selon le principe de l'échec, itérateur sera lancé immédiatement.
java.util.concurrentModificationException Exception.
Par conséquent, Iterator n'autorise pas les objets itérés à modifier lorsqu'il fonctionne.
Mais vous pouvez utiliser la propre méthode de l'itérateur remove() pour supprimer l'objet. Iterator.remove() conservera la cohérence de l'index lors de la suppression de l'objet itéré actuel.
Supprimer correctement les éléments pendant la traversée:
Iterator <Student> Stumer = Students.Iterator (); while (stututer.hasnext ()) {étudiant étudiant = stututer.next (); if (Student.getId () == 2) sttuer.remove (); // Ici, vous devez utiliser la méthode de suppression de l'itérateur pour supprimer l'objet actuel. Si vous utilisez la méthode de suppression de la liste, ConcurrentModificationException apparaîtra également} Ok, ici, je vous présenterai le principe de mise en œuvre de l'amélioration de la boucle pour les pièges et des pièges dans lesquels vous pourriez tomber si vous l'utilisez mal. Par conséquent, bien qu'il s'agisse d'une simple syntaxe pour chaque fois, vous devez également comprendre ses principes, sinon cela peut entraîner des problèmes inexplicables.
Résumer
Ce qui précède est l'intégralité du contenu de cet article. J'espère que le contenu de cet article a une certaine valeur de référence pour l'étude ou le travail de chacun. Si vous avez des questions, vous pouvez laisser un message pour communiquer. Merci pour votre soutien à wulin.com.