1633 votes

Comment le Java pour chaque boucle de travail?

List<String> someList = new ArrayList<String>();
// add "monkey", "donkey", "skeleton key" to someList
for (String item : someList) {
    System.out.println(item);
}

Ce serait l'équivalent de la boucle ressembler, sans l'aide de la syntaxe?

1261voto

nsayer Points 5594
for(Iterator<String> i = someList.iterator(); i.hasNext(); ) {
    String item = i.next();
    System.out.println(item);
}

Notez que si vous devez utiliser i.remove(); dans votre boucle, ou l'accès au réel iterator , d'une certaine façon, vous ne pouvez pas utiliser l' for( : ) idiome, puisqu'il s' Iterator est simplement déduite.

Comme l'a souligné Denis Bueno, ce code fonctionne pour n'importe quel objet qu' implements le Iterable interface.

Aussi, si le côté droit de l' for(:) idiome est une array plutôt qu'un Iterable objet, le code interne utilise un int index du compteur et les contrôles contre le tableau.la longueur de la place. Voir la Java Language Specification.

538voto

Mikezx6r Points 6541

Puisque je ne peux pas éditer/commenter, ici, est mon plus.

pour chacun d'eux est également valable pour les tableaux. par exemple

int[] test = new int[]{1,4,5,7};
for (int intValue : test) {
    // do some work here on intValue
}

Donc, en résumé:
[nsayer]La suite est de la forme longue de ce qui se passe:

for(Iterator<String> i = someList.iterator(); i.hasNext(); ) {
  String item = i.next();
  System.out.println(item);
}

Notez que si vous avez besoin d'utiliser j'.remove(); dans la boucle, ou de l'accès le réel de l'itérateur d'une certaine façon, vous ne peut pas utiliser le( : ) l'idiome, depuis le réel de l'Itérateur est simplement déduite.

[Denis Bueno]

Il est implicite par nsayer réponse, mais il est intéressant de noter que la Fpo pour(..) la syntaxe du travail lors de la "someList" est tout ce qui met en œuvre java.lang.Itérable -- il n'a pas pour être une liste ou un ensemble de java.util. Même vos propres types, par conséquent, peut être utilisé avec ce la syntaxe.

Réponse à Konrad Rudolph commentaire

  1. Afin de recueillir l'ensemble des informations en un seul endroit, donc il y a une réponse complète (n'est-ce pas le point de la SORTE?)
  2. AJOUTER le fait qu'il s'applique également aux tableaux (ce qui n'est pas mentionné auparavant, au temps de mon affichage.)
  3. Parce que je n'ai pas la rep à modifier de quelqu'un d'autre poste pour ajouter mes pensées ou ajouter un commentaire à mentionner qu'il fonctionne sur les tableaux.

180voto

aliteralmind Points 6583

L' foreach boucle, ajoutée dans Java 5 (également appelé le "enhanced pour la boucle"), est équivalent à l'utilisation d'un java.util.Iterator--c'est du sucre syntaxique pour la même chose. Par conséquent, lors de la lecture de chaque élément un par un et dans l'ordre, un foreach doit toujours être choisie sur un itérateur, comme il est plus pratique et concis.

foreach

for(int i : intList)  {
   System.out.println("An element in the list: " + i);
}

Itérateur

Iterator<Integer> intItr = intList.iterator();
while(intItr.hasNext())  {
   System.out.println("An element in the list: " + intItr.next());
}

Il y a des situations où vous devez utiliser un Iterator directement. Par exemple, tentez de supprimer un élément, tout en utilisant un foreach peut (va?) résultat en ConcurrentModificationException.

foreach vs for: différences Fondamentales

La seule différence pratique entre for et foreach , c'est que, dans le cas de plaquettes indexables objets, vous n'avez pas accès à l'index. Un exemple lorsque la base for boucle est nécessaire:

for(int i = 0; i < array.length; i++)  {
   if(i < 5)  {
      //Do something special
   }  else  {
      //Do other stuff
   }
}

Bien que vous pouvez créer manuellement un index séparé int-variable foreach

int idx = -1;
for(int i : intArray)  {
   idx++;
   ...
}

il n'est pas recommandé, car la variable de portée n'est pas l'idéal, et la base for boucle est tout simplement le standard et le format attendu pour ce cas d'utilisation.

foreach vs for: Performance

Lors de l'accès aux collections, foreach est nettement plus rapide que la base for de la boucle d'accès au tableau. Lors de l'accès à des tableaux, cependant, au moins primitif, et l'enveloppe-tableaux--l'accès par index est considérablement plus rapide.

Calendrier de la différence entre itérateur et de l'indice d'accès pour la primitive int-tableaux

Les index sont de 23à 40 pour cent plus rapide que les itérateurs, lors de l'accès int ou Integer tableaux. Voici le résultat de l'essai de la classe au bas de ce post, qui sommes les numéros dans une 100 élément primitif-int array (est Un itérateur, B est l'indice):

[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 358,597,622 nanoseconds
Test B: 269,167,681 nanoseconds
B faster by 89,429,941 nanoseconds (24.438799231635727% faster)

[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 377,461,823 nanoseconds
Test B: 278,694,271 nanoseconds
B faster by 98,767,552 nanoseconds (25.666236154695838% faster)

[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 288,953,495 nanoseconds
Test B: 207,050,523 nanoseconds
B faster by 81,902,972 nanoseconds (27.844689860906513% faster)

[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 375,373,765 nanoseconds
Test B: 283,813,875 nanoseconds
B faster by 91,559,890 nanoseconds (23.891659337194227% faster)

[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 375,790,818 nanoseconds
Test B: 220,770,915 nanoseconds
B faster by 155,019,903 nanoseconds (40.75164734599769% faster)

[C:\java_code\]java TimeIteratorVsIndexIntArray 1000000
Test A: 326,373,762 nanoseconds
Test B: 202,555,566 nanoseconds
B faster by 123,818,196 nanoseconds (37.437545972215744% faster)

J'ai aussi couru ce pour un Integer tableau, et les indices sont encore le gagnant clair, mais uniquement entre 18 et 25 pour cent plus rapide.

Pour les collections, les itérateurs sont plus rapides que les indices

Pour un List de Integers, cependant, les itérateurs sont le gagnant clair. Il suffit de changer le type int-tableau dans le test de la classe de

List<Integer> intList = Arrays.asList(new Integer[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100});

et de faire le nécessaire qu'il change pour le test de fonction (int[] de List<Integer>, length de size(), etc)

[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 3,429,929,976 nanoseconds
Test B: 5,262,782,488 nanoseconds
A faster by 1,832,852,512 nanoseconds (34.326681820485675% faster)

[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 2,907,391,427 nanoseconds
Test B: 3,957,718,459 nanoseconds
A faster by 1,050,327,032 nanoseconds (26.038700083921256% faster)

[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 2,566,004,688 nanoseconds
Test B: 4,221,746,521 nanoseconds
A faster by 1,655,741,833 nanoseconds (38.71935684115413% faster)

[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 2,770,945,276 nanoseconds
Test B: 3,829,077,158 nanoseconds
A faster by 1,058,131,882 nanoseconds (27.134122749113843% faster)

[C:\java_code\]java TimeIteratorVsIndexIntegerList 1000000
Test A: 3,467,474,055 nanoseconds
Test B: 5,183,149,104 nanoseconds
A faster by 1,715,675,049 nanoseconds (32.60101667104192% faster)

[C:\java_code\]java TimeIteratorVsIndexIntList 1000000
Test A: 3,439,983,933 nanoseconds
Test B: 3,509,530,312 nanoseconds
A faster by 69,546,379 nanoseconds (1.4816434912159906% faster)

[C:\java_code\]java TimeIteratorVsIndexIntList 1000000
Test A: 3,451,101,466 nanoseconds
Test B: 5,057,979,210 nanoseconds
A faster by 1,606,877,744 nanoseconds (31.269164666060377% faster)

Dans un test, ils sont presque équivalent, mais avec des collections, itérateur gagne.

Ce poste est basé sur deux réponses que j'ai écrit sur stackexchange:

Uses and syntax for for-each loop in Java

Plus d'information:

Le test complet de la classe

J'ai créé ce compare-le-temps-elle-prend-pour-faire-tout-de deux choses classe après la lecture de cette question sur

Should I use an Iterator or a forloop to iterate?

134voto

MRocklin Points 2855

Voici une réponse qui ne suppose pas de connaissances de Java Itérateurs. Il est moins précis, mais est utile pour l'éducation.

Alors que la programmation nous souvent écrire du code qui ressemble à ceci:

char[] grades = ....
for(int i = 0; i < grades.length; i++)   // for i goes from 0 to grades.length
    System.out.print(grades[i]);         // print grades[i]

La syntaxe foreach permet à ce modèle commun d'être écrites dans un ordre plus naturel et moins d'un point de vue syntaxique bruyant.

for(char grade : grades)      // foreach grade in grades
    System.out.print(grade);  // print that grade

De plus, cette syntaxe est valable pour des objets tels que des Listes ou des Jeux qui ne prennent pas en charge tableau d'indexation, mais qui n'en œuvre la Java Itératif de l'interface.

44voto

toluju Points 2555

La boucle for-each en java utilise le sous-jacent itérateur mécanisme. Il est donc identique à celui-ci:

Iterator<String> iterator = someList.iterator();

while (iterator.hasNext()) {
  String item = iterator.next();
  System.out.println(item);
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X