web-dev-qa-db-fra.com

Itérer avec la boucle for ou la boucle while?

Je vois souvent du code comme:

Iterator i = list.iterator();
while(i.hasNext()) {
    ...
}

mais j'écris cela (quand Java 1.5 n'est pas disponible ou pour chacun ne peut pas être utilisé) comme:

for(Iterator i = list.iterator(); i.hasNext(); ) {
    ...
}

car

  • C'est plus court
  • Il conserve i dans une portée plus petite
  • Cela réduit les risques de confusion. (i est-il utilisé en dehors du temps? Où est déclaré i?)

Je pense que le code devrait être aussi simple à comprendre que possible afin que je n'aie qu'à créer du code complexe pour faire des choses complexes. Qu'est-ce que tu penses? Ce qui est mieux?

De: http://jamesjava.blogspot.com/2006/04/iterating.html

41

Je préfère la boucle for car elle définit également la portée de l'itérateur sur la boucle for uniquement.

81
Lou Franco

Il existe des utilisations appropriées pour les constructions while, for et foreach:

  • while - Utilisez ceci si vous êtes en train d'itérer et que le facteur décisif pour boucler ou non est basé simplement sur une condition. Dans cette construction en boucle, conserver un index n'est qu'une préoccupation secondaire; tout devrait être basé sur la condition

  • for - Utilisez ceci si vous bouclez et que votre préoccupation principale est l'index du tableau/collection/liste. Il est plus utile d'utiliser un pour si vous êtes le plus susceptible de parcourir tous les éléments de toute façon, et dans un ordre particulier (par exemple, revenir en arrière dans une liste triée, par exemple).

  • foreach - Utilisez-le si vous avez simplement besoin de parcourir votre collection quelle que soit la commande.

Évidemment, il y a des exceptions à ce qui précède, mais c'est la règle générale que j'utilise lorsque je décide de l'utiliser. Cela étant dit, j'ai tendance à utiliser foreach plus souvent.

10
Jon Limjap

Pourquoi ne pas utiliser la construction for-each? (Je n'ai pas utilisé Java depuis un certain temps, mais cela existe en C # et je suis presque sûr Java 1.5 l'a aussi)):

List<String> names = new ArrayList<String>();
names.add("a");
names.add("b");
names.add("c");

for (String name : names)
    System.out.println(name.charAt(0));
6
Giorgio Galante

Je pense que la portée est le plus gros problème ici, comme vous l'avez souligné.

Dans l'exemple "while", l'itérateur est déclaré en dehors de la boucle, il continuera donc d'exister une fois la boucle terminée. Cela peut entraîner des problèmes si ce même itérateur est utilisé à nouveau ultérieurement. Par exemple. vous pouvez oublier de l'initialiser avant de l'utiliser dans une autre boucle.

Dans l'exemple "for", l'itérateur est déclaré à l'intérieur de la boucle, donc sa portée est limitée à la boucle. Si vous essayez de l'utiliser après la boucle, vous obtiendrez une erreur de compilation.

4
Dima

À mon humble avis, la boucle for est moins lisible dans ce scénario, si vous regardez ce code du point de vue de la langue anglaise. Je travaille sur un code où l'auteur abuse de la boucle for, et ce n'est pas joli. Comparez les éléments suivants:

for (; (currUserObjectIndex < _domainObjectReferences.Length) && (_domainObjectReferences[currUserObjectIndex].VisualIndex == index); ++currUserObjectIndex)
    ++currNumUserObjects;

contre

while (currUserObjectIndex < _domainObjectReferences.Length && _domainObjectReferences[currUserObjectIndex].VisualIndex == index)
{
    ++currNumUserObjects;
    ++currUserObjectIndex;
}
2
Igor Vaschuk

si vous n'utilisez l'itérateur qu'une seule fois et que vous le jetez, la deuxième forme est préférable; sinon vous devez utiliser le premier formulaire

2
Steven A. Lowe

En utilisant la boucle for, vous pouvez travailler avec une seule variable, car elle définit la portée de la variable pour une boucle fonctionnant actuellement uniquement. Cependant, cela n'est pas possible dans la boucle while. Par exemple:
int i; pour (i = 0; in1; i ++) faire quelque chose ..

car (i = 0; i n2; i + = 2) faites quelque chose.

Donc après la 1ère boucle i = n1-1 à la fin. Mais en utilisant la deuxième boucle, vous pouvez remettre i à 0. Cependant

int i = 0;

while (i less than limit) {fais quelque chose ..; i ++; }

Par conséquent, i est défini sur limit-1 à la fin. Vous ne pouvez donc pas utiliser le même i dans une autre boucle while.

1
Abhishek Kaushik

Je conviens que la boucle "for" est plus claire et plus appropriée lors de l'itération.

La boucle "while" est appropriée pour l'interrogation, ou lorsque le nombre de boucles pour répondre à la condition de sortie changera en fonction de l'activité à l'intérieur de la boucle.

1
Guy Starbuck

Non pas que cela importe probablement dans ce cas, mais les compilateurs, les machines virtuelles et les processeurs ont normalement des techniques d'optimisation spéciales qu'ils utilisent sous le capot qui amélioreront les performances des boucles (et dans un proche avenir), en général, ils ne le font pas avec tandis que les boucles (car il est plus difficile de déterminer comment cela va réellement fonctionner). Mais dans la plupart des cas, la clarté du code devrait l'emporter sur l'optimisation.

1
Robert Gould

N'importe quel. J'utilise pour () moi-même, et je ne sais pas s'il y a des problèmes de compilation. Je soupçonne qu'ils sont tous les deux optimisés pour à peu près la même chose.

0
scubabbl

Bien que les deux soient très bien, j'ai tendance à utiliser le premier exemple car il est plus facile à lire.

Il y a moins d'opérations qui se produisent sur chaque ligne avec la boucle while (), ce qui facilite la compréhension du code par une personne nouvelle dans le code.

Ce type de construction me permet également de regrouper les initialisations dans un emplacement commun (en haut de la méthode), ce qui simplifie également les commentaires pour moi et la conceptualisation pour quelqu'un qui le lit pour la première fois.

0
Ron Savage

Les deux sont très bien, mais rappelez-vous que parfois l'accès à l'itérateur directement est utile (comme si vous supprimez des éléments qui correspondent à une certaine condition - vous obtiendrez une exception ConcurrentModificationException si vous faites collection.remove (o) à l'intérieur d'un for (T o: collection)).

Je préfère écrire la syntaxe for (blah: blah) [foreach] presque tout le temps parce qu'elle me semble plus naturellement lisible. Le concept d'itérateurs en général n'a pas vraiment de parallèles en dehors de la programmation

0
Mat Mannion

Je suis d'accord que la boucle for devrait être utilisée dans la mesure du possible, mais il existe parfois une logique plus complexe qui contrôle l'itérateur dans le corps de la boucle. Dans ce cas, vous devez aller avec tout.

0
Svet

J'étais la boucle for pour plus de clarté. Alors que j'utilise la boucle while face à une condition non déterministe.

0
jehanzeb.naeem.khan

Le milieu universitaire a tendance à préférer la boucle while car elle rend le raisonnement moins compliqué sur les programmes. J'ai tendance à préférer les structures pour ou pour chaque boucle car elles rendent le code plus facile à lire.

0
James Muscat