Pourquoi utiliser un iterator au lieu d'un for ? [résolu] - Java - Programmation
Marsh Posté le 09-09-2010 à 20:31:55
En quoi ca hausse le niveau d'abstraction ? et pour quoi faire ?
Marsh Posté le 10-09-2010 à 12:03:05
Une différence majeure est que un intérateur va itérer du noeud courant vers le suivant, cad qu'il n'y a rien ou presque à faire, juste suivre un pointeur.
Un for va impliquer de pointer les éléments de la liste par liste.get(i) par ex. Du coup à chaque itération la liste va devoir chercher les éléments parmi tous ses éléments, ce qui est plu long potentiellement.
Je ne sais pas si c'est la seule raison, mais ça en est une.
Marsh Posté le 11-09-2010 à 00:14:13
Mouai, mouai ...
Puisque personne ne sait répondre clairement,
Il me semble que la différence c'est que l'itérator est thread-safe (ConcurrentModificationException) alors qu'en utilisant un for, on ne se prémunit pas d'une modification en cours de lecture.
Marsh Posté le 11-09-2010 à 09:46:19
rien a voir. La concurentModificationException n'est pas une notion sur les thread, tu peux lever cette exception en mono thread (rajoute un élément sur ta collection dans le boucle de ton itérator).
Non, la vraie raison, c'est : "je parcours ma collection sans tenir compte du fait qu'il s'agit d'une collection indexée ou une collection chainée, donc sans m'interresser du tout au format interne de ma collection, boite noire, tout ça"
Marsh Posté le 11-09-2010 à 11:55:37
Que ce soit une liste chainée (LinkedList) ou une liste indexée (ArrayList), on a la possibilité d'itérer dessus via un for sans se soucier du type de list.
Par contre tu as raison pour les Set, car je viens de remarquer qu'ils implémentent bien l'interface Collection mais qu'il n'y a pas de méthode get(int index) dessus !
Du coup obligé de passer par un iterator.
Marsh Posté le 11-09-2010 à 12:00:20
Sinon je persiste, concurentModificationException est liée à la notion de thread même si on peut la lever en monothread.
Citation : public class ConcurrentModificationException This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible. For example, it is not generally permssible for one thread to modify a Collection while another thread is iterating over it. |
Marsh Posté le 12-09-2010 à 13:29:05
pharaon2005 a écrit : |
Oui, mais les performances ne seront pas forcément équivalentes. Niveau perf, pour une ArrayList, ça revient au même d'utiliser un Iterator ou de faire des get(index) dans une boucle for, mais pour une LinkedList, l'iterator sera beaucoup plus efficace.
C'est tout l'intérêt de ce niveau d'abstraction supplémentaire : on n'a pas besoin de connaitre les détails de l'implémentation de la liste pour la parcourir de façon optimale.
Marsh Posté le 12-09-2010 à 16:09:04
Riokmij a écrit : Oui, mais les performances ne seront pas forcément équivalentes. Niveau perf, pour une ArrayList, ça revient au même d'utiliser un Iterator ou de faire des get(index) dans une boucle for, mais pour une LinkedList, l'iterator sera beaucoup plus efficace. C'est tout l'intérêt de ce niveau d'abstraction supplémentaire : on n'a pas besoin de connaitre les détails de l'implémentation de la liste pour la parcourir de façon optimale. |
Faux.
Citation : In practice, is it as efficient to traverse a LinkedList using a for-each loop as it is to use an iterator? |
http://www.dreamincode.net/forums/ [...] rformance/
Marsh Posté le 12-09-2010 à 18:23:39
pharaon2005 a écrit : Sinon je persiste, concurentModificationException est liée à la notion de thread |
Non. C'est pas parce qu'ils donnent un exemple parlant de threads que c'est lié à la notion de threads. C'est juste que tu as plus de chance de te bouffer une CME quand tu sais pas ce que tes threads foutent, ce qui est probablement le cas.
pharaon2005 a écrit : Faux.
|
C'est marrant, parce que mon JDK a pas du tout l'air d'accord
Sur une liste de 100000 éléments, ce code:
Code :
|
prend ~20s sur un i5 2.4GHz (test effectué 5 fois de suite, doStuff ne fait qu'incrémenter un compteur)
Alors que ce code:
Code :
|
prend 17ms la première fois qu'il tourne et moins d'une milliseconde le reste du temps (5 tests de suite, pareil qu'au dessus) (timings à la va-vite via System.currentTimeMillis, mais ça explique pas d'avoir 5 ordres de grandeur de différence)
Je t'encourage à faire le test toi même si tu ne me crois pas
Mais si tu savais de quoi tu parlais, tu aurais vite réalisé que ce que tu as cité n'avait aucun sens: l'indexation d'une LinkedList se fait en O(n), donc à chaque fois que tu fais un lst.get(i) il faut traverser toute la liste élément par élément jusqu'à trouver le bon...
Marsh Posté le 12-09-2010 à 19:23:27
masklinn a écrit :
|
Désolé, l'accès concurrent est principalement lié aux thread.
masklinn a écrit :
Sur une liste de 100000 éléments, ce code:
Alors que ce code:
Je t'encourage à faire le test toi même si tu ne me crois pas
Mais si tu savais de quoi tu parlais, tu aurais vite réalisé que ce que tu as cité n'avait aucun sens: l'indexation d'une LinkedList se fait en O(n), donc à chaque fois que tu fais un lst.get(i) il faut traverser toute la liste élément par élément jusqu'à trouver le bon... |
Tu me fais bien rigoler. On parle de comparer un iterator avec une boucle for, toi tu compares la boucle for avec la boucle for-each.
Bon j'ai fait le test. 15 ms pour l'iterator et 15 ms pour le for-each et 48750 ms pour un for (10 000 de integer).
Conclusion : le for-each et l'iterator sont équivalents pour toutes les Collection, le for classique est beaucoup plus long avec une LinkedList et pas utilisable avec les Set.
Marsh Posté le 12-09-2010 à 20:13:07
pharaon2005 a écrit : |
bah et pour cause, c'est la même chose foreach est juste un sucre syntaxique
Marsh Posté le 12-09-2010 à 20:14:47
pharaon2005 a écrit : Désolé, l'accès concurrent est principalement lié aux thread. |
Non. Il y a des tas de cas où on peut avoir des accès à la collection sous-jacente sans avoir besoin de threads. En tout cas, toutes les fois où j'ai rencontré ce genre de problèmes, ce n'était jamais lié aux threads.
pharaon2005 a écrit : Tu me fais bien rigoler. On parle de comparer un iterator avec une boucle for, toi tu compares la boucle for avec la boucle for-each. |
Tu sais comment est implémentée la boucle foreach pour les collections ? Bingo, c'est un Iterator !
Ce code :
Code :
|
est exactement équivalent à :
Code :
|
Le foreach, c'est juste du sucre syntaxique.
EDIT : grillé
Marsh Posté le 12-09-2010 à 20:25:41
kadreg a écrit : |
+1
Le Pharaon ne sait pas faire la différence entre un foreach et une boucle for( ; ; )
Marsh Posté le 12-09-2010 à 20:34:45
Bon on est d'accord la-dessus ?
Citation : Conclusion : le for-each et l'iterator sont équivalents pour toutes les Collection, le for classique est beaucoup plus long avec une LinkedList et pas utilisable avec les Set. |
Le topic est clos.
Marsh Posté le 13-09-2010 à 05:01:59
pharaon2005 a écrit : Désolé, l'accès concurrent est principalement lié aux thread. |
T'as encore rien compris au film toi
pharaon2005 a écrit : |
Continues à creuser, tu vas bientôt découvrir que la terre n'est pas plate avec un peu de bol.
pharaon2005 a écrit : |
Non mais s'tu veux c'est dans la définition du foreach Java, faut être toi pour pas être au courant
Marsh Posté le 13-09-2010 à 11:36:31
masklinn a écrit : |
masklinn a écrit : |
masklinn a écrit : |
Ouai désolé je suis pas
Les débats de ca peut tourner en rond pendant longtemps.
Bref, on va arrêter là y a plus rien de constructif
Marsh Posté le 13-09-2010 à 12:00:42
pharaon2005 a écrit : Ouai désolé je suis pas |
Non mais ya jamais eu de débat en fait, ya juste eu les autres (qui ont la réalité de leur côté) et toi (qui se vautre comme une grosse otarie bourrée)
pharaon2005 a écrit : Bref, on va arrêter là y a plus rien de constructif |
Oh ben zute alors, c'est sûr que tu faisais avancer la connaissance humaine avec des débarquements tels que
pharaon2005 a écrit : Tu me fais bien rigoler. On parle de comparer un iterator avec une boucle for, toi tu compares la boucle for avec la boucle for-each. |
Marsh Posté le 13-09-2010 à 16:02:42
masklinn a écrit : |
masklinn a écrit : |
Mais oui c'est bien mon gros
Allez ...
Marsh Posté le 14-09-2010 à 06:37:33
hydrogene a écrit : |
Et des multis pourris en bonus, tu t'es fait cracotter
Marsh Posté le 17-10-2010 à 11:39:04
C'est pareil.
A la compilation la boucle "for each" est interprétée comme un objet implémentant la classe iterable.
La notation a été introduite dans java 5 pour faciliter la lecture.
Marsh Posté le 08-09-2010 à 20:34:18
En gros, quel est l'intérêt d'utiliser un iterator au lieu d'une boucle for ou while ?
Question existentielle
Message édité par pharaon2005 le 12-09-2010 à 20:00:06