Essayez-vous réellement d'éviter l'utilisation d'un itérateur, ou ne voulez-vous simplement pas le voir dans votre code source ?
Jon Skeet
2
Vous pouvez rendre le code plus court et plus propre, mais vous devez utiliser un itérateur. Y a-t-il une raison pour laquelle vous voulez l'éviter?
Peter Lawrey
5
Juste pour mémoire et pour expliquer pourquoi éviter l'itérateur: je suis actuellement confronté à ce problème dans un jeu Android écrit en Java. En ce moment, j'utilise un HashSet pour stocker les auditeurs qui doivent être régulièrement informés des événements. Cependant, l'itération répétée des collections provoque une activité importante de ramasse-miettes qui peut surcharger la boucle de jeu. Et c'est un non-go dans un jeu Java. Je vais réécrire ces parties.
tiguchi
12
@thecoshman Je ne parle que du point de vue du développement de jeux Java où vous voulez éviter à tout prix le GC lors des mises à jour régulières de l'état du jeu. Les itérateurs ne sont que des objets temporairement utiles car vous ne pouvez pas les réinitialiser au début, ils sont donc recréés à chaque appel de méthode d'itération (voir la source ArrayList.java par exemple). S'il est utilisé dans une boucle de jeu pour itérer des objets de scène et compte tenu d'au moins 30 mises à jour par seconde, vous vous retrouvez avec au moins 60 (la scène est généralement répétée deux fois par cycle) des objets itérateurs par seconde en mémoire en attente de GC. Cela a un grand impact sur Android.
tiguchi
9
Peut-être faudrait-il choisir une structure de données plus adéquate dans ce cas? Un ensemble n'est pas conçu pour répéter efficacement. Pourquoi ne pas utiliser une ArrayList et itérer dessus avec une boucle for standard? Aucun itérateur supplémentaire n'est créé, l'accès en lecture est très rapide.
Je crois que cela utilise un itérateur dans les coulisses.
munyengm
22
@munyengm Oui, c'est le cas. Il n'y a aucun moyen d'itérer sur un ensemble sans itérateur, à part accéder à la structure sous-jacente qui contient les données par réflexion et répliquer le code fourni par Set # iterator ...
assylias
1
Cela fonctionne, mais si cela peut poser des problèmes, ce n'est pas la solution pour moi. Je suppose que je n'ai pas le choix, je dois utiliser Iterator. Merci pour tout de toute façon.
user1621988
39
@ user1621988 Quels problèmes? Il n'y a aucun problème avec le code que j'ai fourni. Il fournit simplement un moyen agréable et propre d'itérer sur un ensemble sans avoir à utiliser explicitement un itérateur.
assylias
90
Il existe au moins six façons supplémentaires d'itérer sur un ensemble. Je connais les éléments suivants:
Méthode 1
// Obsolete CollectionEnumeration e =newVector(movies).elements();while(e.hasMoreElements()){System.out.println(e.nextElement());}
Méthode 2
for(String movie : movies){System.out.println(movie);}
Méthode 3
String[] movieArray = movies.toArray(newString[movies.size()]);for(int i =0; i < movieArray.length; i++){System.out.println(movieArray[i]);}
Méthode 4
// Supported in Java 8 and above
movies.stream().forEach((movie)->{System.out.println(movie);});
Méthode 5
// Supported in Java 8 and above
movies.stream().forEach(movie ->System.out.println(movie));
Méthode 6
// Supported in Java 8 and above
movies.stream().forEach(System.out::println);
C'est ce HashSetque j'ai utilisé pour mes exemples:
Set<String> movies =newHashSet<>();
movies.add("Avatar");
movies.add("The Lord of the Rings");
movies.add("Titanic");
L'instruction for a un formulaire conçu pour l'itération à travers les collections et les tableaux. Ce formulaire est parfois appelé l'instruction for améliorée, et peut être utilisé pour rendre vos boucles plus compactes et plus faciles à lire.
defaultvoid forEach(Consumer<?super T> action)Performs the given action for each element of the Iterable until all elements have been processed or the action throws an exception.Unless otherwise specified by the implementing class, actions are performed in the order of iteration (if an iteration order is specified).Exceptions thrown by the action are relayed to the caller.ImplementationRequirements:Thedefault implementation behaves as if:for(T t :this)
action.accept(t);Parameters: action -The action to be performed for each element
Throws:NullPointerException-if the specified action is nullSince:1.8
Cependant, de très bonnes réponses sont déjà disponibles pour cela. Voici ma réponse:
1. set.stream().forEach(System.out::println);// It simply uses stream to display set values2. set.forEach(System.out::println);// It uses Enhanced forEach to display set values
De plus, si cet ensemble est de type Classe personnalisée, par exemple: Client.
Réponses:
Vous pouvez utiliser une boucle for améliorée :
Ou avec Java 8:
la source
Il existe au moins six façons supplémentaires d'itérer sur un ensemble. Je connais les éléments suivants:
Méthode 1
Méthode 2
Méthode 3
Méthode 4
Méthode 5
Méthode 6
C'est ce
HashSet
que j'ai utilisé pour mes exemples:la source
stream()
.La conversion de votre ensemble en tableau peut également vous aider à parcourir les éléments:
la source
toArray
appelle l'itérateur de l'ensemble.Pour démontrer, considérons l'ensemble suivant, qui contient différents objets Person:
la source
Vous pouvez utiliser une opération fonctionnelle pour un code plus soigné
la source
Voici quelques conseils sur la façon d'itérer un ensemble ainsi que ses performances:
Le code est explicite.
Les résultats des durées sont:
Nous pouvons voir que la
Lambda
prise est la plus longue etIterator
la plus rapide.la source
Énumération(?):
Une autre façon (java.util.Collections.enumeration ()):
Java 8:
ou
la source
Cependant, de très bonnes réponses sont déjà disponibles pour cela. Voici ma réponse:
De plus, si cet ensemble est de type Classe personnalisée, par exemple: Client.
// Classe de client:
la source