La différence entre le déplacement d'un Iterator avant avec une déclaration pour et une déclaration while

StackOverflow https://stackoverflow.com/questions/515562

Question

Quand j'utilise un itérateur d'objets que j'utilise un while (comme écrit dans tous les livres d'apprentissage Java, Penser en Java de Bruce Eckel):

Iterator it=...

while(it.hasNext()){
    //...
}

mais parfois j'ai vu que quelqu'un au lieu d'utiliser la pour la boucle :

Iterator it=...
for (Iterator it=...; it.hasNext();){
    //...
}

Je ne comprends pas ce choix:

  • J'utilise le boucle quand j'ai une collection avec une séquence ordinale (sous forme de tableau), soit avec une règle particulière pour l'étape (déclarée généralement comme un incrément simple, counter++).
  • J'utilise le while lorsque la boucle se termine par je have'nt ces contraintes, mais seulement une condition logique pour la sortie.

Il est une question de style de codage sans autre cause ou il existe une autre logique (performance, par exemple) que je ne » sais?

Merci pour tous les commentaires

Était-ce utile?

La solution

La syntaxe correcte pour la boucle est:

for (Iterator it = ...; it.hasNext(); ){
    //...
}

(La déclaration qui précède dans votre code est superflu, ainsi que le point-virgule supplémentaire dans la rubrique pour la boucle.)

Si vous utilisez cette syntaxe ou la boucle est une question while de goût, à la fois traduire exactement la même chose. La syntaxe générique de la boucle est:

for (<init stmt>; <loop cond>; <iterate stmt>) { <body>; }

qui est équivalent à:

<init stmt>;
while (<loop cond>) { <body>; <iterate stmt>; }

Modifier En fait, les deux formes ci-dessus ne sont pas tout à fait équivalent, si (comme dans la question) la variable est déclarée avec l'instruction init. Dans ce cas, il y aura la différence dans le cadre de la variable itérateur. Avec la boucle, la portée est limitée à la boucle elle-même, dans le cas de la boucle while, toutefois, la portée étend jusqu'à la fin du bloc englobante (pas grand surprise, puisque la déclaration est en dehors de la boucle).

En outre, comme d'autres l'ont souligné, dans les nouvelles versions de Java, il y a une abbréviation de la boucle:

for (Iterator<Foo> it = myIterable.iterator(); it.hasNext(); ) {
    Foo foo = it.next();
    //...
}

peut être écrit comme:

for (Foo foo : myIterable) {
    //...
}

Avec ce formulaire, vous perdez bien sûr la référence directe à l'itérateur, qui est nécessaire, par exemple, si vous souhaitez supprimer des éléments de la collection en itérer.

Autres conseils

Il est juste une chose de style et comme vous je préfère la boucle lorsque vous utilisez quelque chose avec un index. Si vous utilisez Java 5, vous devez bien sûr utiliser une boucle foreach sur la collection de toute façon:

Collection<String> someCollection = someCollectionOfString();
for (String element : someCollection) {
....
}

Le but de déclarer l'intérieur de la Iterator boucle est minimiser la portée de vos variables , ce qui est une bonne pratique.

Lorsque vous déclarez l'extérieur de la <=> boucle, la référence est toujours valide / vie après la boucle complète. 99,99% du temps, vous n'avez pas besoin de continuer à utiliser la boucle une fois que la <=> complète, de sorte qu'un tel style peut conduire à des bugs comme ceci:

//iterate over first collection
Iterator it1 = collection1.iterator();
while(it1.hasNext()) {
   //blah blah
}

//iterate over second collection
Iterator it2 = collection2.iterator();
while(it1.hasNext()) {
   //oops copy and paste error! it1 has no more elements at this point
}

Il n'y a pas beaucoup de différence entre ces deux méthodes, autre que le premier se souvient après la boucle la valeur de it. La deuxième approche jette probablement une erreur, parce que vous redéclarer la variable dans la boucle.

Il y a en fait une troisième méthode pour cela, aswell. Au lieu d'écrire par exemple.

for (Iterator<SomeObject> it = foo.iterator(); it.hasNext();) {
  SomeObject so = foo.next();
}

vous pouvez écrire le plus souvent

for (SomeObject so: foo) {...}

Ces deux égaux à la même chose ...

Les gens peuvent utiliser l'explicite ( « ancien style ») pour la boucle simplement parce qu'il se sent plus propre à eux, peut-être qu'ils ne sont pas adaptés à la nouvelle syntaxe encore (que je pense personnellement est beaucoup plus propre).

Un avantage spécifique réel de la plus longue construction de boucle est que vous avez une référence à l'itérateur et ne peut donc appeler des méthodes sur elle puis d'autres next(). En particulier, peut souvent être hasNext() utile d'appeler - imaginez si vous voulez imprimer une liste de chaînes séparées par des virgules:

StringBuilder sb = new StringBuilder();
for (Iterator it=...; it.hasNext();){
   sb.append(it.next());
   if (it.hasNext())
      sb.append(", ");
}

Il est seulement de distinguer la «c'est le dernier » cas comme celui-ci si vous utilisez le plus bavard boucle.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top