Considérer:
List<String> someList = new ArrayList<String>();
// add "monkey", "donkey", "skeleton key" to someList
for (String item : someList) {
System.out.println(item);
}
À quoi for
ressemblerait la boucle équivalente sans utiliser la pour chaque syntaxe?
java
foreach
syntactic-sugar
Jay R.
la source
la source
Réponses:
Notez que si vous devez utiliser
i.remove();
dans votre boucle ou accéder à l'itérateur réel d'une manière ou d'une autre, vous ne pouvez pas utiliser l'for ( : )
idiome, car l'itérateur réel est simplement déduit.Comme l'a noté Denis Bueno, ce code fonctionne pour tout objet qui implémente l'
Iterable
interface .De plus, si le côté droit de l'
for (:)
idiome est unarray
plutôt qu'unIterable
objet, le code interne utilise un compteur d'index int et vérifie à laarray.length
place. Voir la spécification du langage Java .la source
import java.util.Iterator;
etimport java.lang.Iterable;
java.util.Iterator
ne met pas en œuvreIterable
donc vous ne pouvez pasfor(String s : (Iterator<String>)foo)
. Je comprends pourquoi il en est, mais il est irritant.La construction de chacun est également valide pour les tableaux. par exemple
qui est essentiellement équivalent à
Donc, résumé global:
[nsayer] Ce qui suit est la forme la plus longue de ce qui se passe:
[Denis Bueno]
la source
La
foreach
boucle , ajoutée dans Java 5 (également appelée «boucle améliorée»), équivaut à utiliserjava.util.Iterator
le sucre syntaxique d' un --it pour la même chose. Par conséquent, lors de la lecture de chaque élément, un par un et dans l'ordre, unforeach
doit toujours être choisi plutôt qu'un itérateur, car il est plus pratique et concis.pour chaque
Itérateur
Il y a des situations où vous devez utiliser un
Iterator
directement. Par exemple, tenter de supprimer un élément tout en utilisant uneforeach
boîte de conserve (le fera?)ConcurrentModificationException
.foreach
contre.for
: différences fondamentalesLa seule différence pratique entre
for
etforeach
est que, dans le cas d'objets indexables, vous n'avez pas accès à l'index. Un exemple lorsque lafor
boucle de base est requise:Bien que vous puissiez créer manuellement une variable int d'index distincte avec
foreach
,il n'est pas recommandé, car la portée variable n'est pas idéale et la
for
boucle de base est simplement le format standard et attendu pour ce cas d'utilisation.foreach
vsfor
: PerformanceLors de l'accès aux collections, a
foreach
est beaucoup plus rapide que l'for
accès au tableau de la boucle de base . Cependant, lors de l'accès aux tableaux, au moins avec les tableaux primitifs et wrapper, l'accès via les index est considérablement plus rapide.Synchronisation de la différence entre l'itérateur et l'accès à l'index pour les tableaux int primitifs
Les index sont 23 à 40 % plus rapides que les itérateurs lors de l'accès
int
ou desInteger
tableaux. Voici la sortie de la classe testing au bas de cet article, qui résume les nombres dans un tableau primitif-int à 100 éléments (A est un itérateur, B est un index):J'ai également exécuté cela pour un
Integer
tableau, et les index sont toujours clairement gagnants, mais seulement entre 18 et 25% plus rapidement.Pour les collections, les itérateurs sont plus rapides que les index
Pour un
List
desIntegers
cependant itérateurs sont le grand vainqueur. Modifiez simplement l'int-array dans la classe de test en:Et apportez les modifications nécessaires à la fonction de test (
int[]
àList<Integer>
,length
àsize()
, etc.):Dans un test, ils sont presque équivalents, mais avec les collections, l'itérateur gagne.
* Ce message est basé sur deux réponses que j'ai écrites sur Stack Overflow:
Utilisations et syntaxe pour chaque boucle en Java
Dois-je utiliser un itérateur ou un forloop pour itérer?
Quelques informations supplémentaires: Quelle est la plus efficace, une boucle pour chaque, ou un itérateur?
La classe de test complète
J'ai créé cette classe de comparaison du temps qu'il faut pour faire deux choses après avoir lu cette question sur Stack Overflow:
la source
for(int value : int_array) {/* loop content */}
c'est le plus lent dans votre test car il est syntaxiquement équivalent àfor(int i = 0; i < int_array.length; i++) {int value = int_array[i]; /* loop content */}
, ce qui n'est pas ce que votre test compare.int value = int_array[i];
au début de leur pour boucle, alors ils pourraient aussi bien utiliser foreach. A moins qu'ils n'aient besoin d'accéder à l'index, pour une raison quelconque. En bref, tout dépend du contexte.)Voici une réponse qui ne suppose pas la connaissance des Java Iterators. C'est moins précis, mais c'est utile pour l'éducation.
Lors de la programmation, nous écrivons souvent du code qui ressemble à ceci:
La syntaxe foreach permet d'écrire ce modèle commun d'une manière plus naturelle et moins bruyante syntaxiquement.
En outre, cette syntaxe est valide pour les objets tels que les listes ou les ensembles qui ne prennent pas en charge l'indexation de tableau, mais qui implémentent l'interface Java Iterable.
la source
La boucle for-each en Java utilise le mécanisme d'itérateur sous-jacent. C'est donc identique à ce qui suit:
la source
Dans les fonctionnalités Java 8, vous pouvez utiliser ceci:
Production
la source
C'est implicite dans la réponse de nsayer, mais il convient de noter que la syntaxe OP pour (..) fonctionnera lorsque "someList" est tout ce qui implémente java.lang.Iterable - il ne doit pas nécessairement s'agir d'une liste ou d'une collection de java.util. Par conséquent, même vos propres types peuvent être utilisés avec cette syntaxe.
la source
Comme défini dans JLS, chaque boucle peut avoir deux formes:
Si le type d'expression est un sous-type, la
Iterable
traduction est la suivante:Si l'expression a nécessairement un type de tableau,
T[]
alors:Java 8 a introduit des flux qui fonctionnent généralement mieux. Nous pouvons les utiliser comme:
la source
Une syntaxe de boucle foreach est:
Exemple:
Production:
AVERTISSEMENT: vous pouvez accéder aux éléments du tableau avec la boucle foreach, mais vous ne pouvez PAS les initialiser. Utilisez la
for
boucle d' origine pour cela.AVERTISSEMENT: vous devez faire correspondre le type du tableau avec l'autre objet.
Si vous souhaitez modifier des éléments, utilisez la
for
boucle d' origine comme ceci:Maintenant, si nous vidons s sur la console, nous obtenons:
la source
La construction de boucle Java "pour chaque" permettra l'itération sur deux types d'objets:
T[]
(tableaux de tout type)java.lang.Iterable<T>
L'
Iterable<T>
interface a une seule méthode:Iterator<T> iterator()
. Cela fonctionne sur les objets de typeCollection<T>
car l'Collection<T>
interface s'étendIterable<T>
.la source
Le concept de boucle foreach tel que mentionné dans Wikipedia est mis en évidence ci-dessous:
Ainsi, le concept d'une boucle foreach décrit que la boucle n'utilise pas de compteur explicite, ce qui signifie qu'il n'est pas nécessaire d'utiliser des index pour parcourir la liste, ce qui évite à l'utilisateur des erreurs ponctuelles. Pour décrire le concept général de cette erreur off-by-one, prenons un exemple de boucle à parcourir dans une liste à l'aide d'index.
Mais supposons que si la liste commence par l'index 1, cette boucle va lever une exception car elle ne trouvera aucun élément à l'index 0 et cette erreur est appelée une erreur hors-ligne. Donc, pour éviter cette erreur de coup par coup, le concept de boucle foreach est utilisé. Il peut y avoir aussi d'autres avantages, mais c'est ce que je pense être le principal concept et l'avantage d'utiliser une boucle foreach.
la source
Dans Java 8, ils ont introduit forEach. À l'aide de cette liste, les cartes peuvent être mises en boucle.
Boucler une liste en utilisant pour chacun
ou
Boucler une carte en utilisant pour chacun
ou
la source
la source
En utilisant des versions Java plus anciennes,
Java 7
vous pouvez utiliser laforeach
boucle comme suit.Voici la toute dernière façon d'utiliser la
foreach
boucle dansJava 8
(boucle une liste avec
forEach
+ expression lambda ou référence de méthode)Pour plus d'informations, reportez-vous à ce lien.
https://www.mkyong.com/java8/java-8-foreach-examples/
la source
Voici une expression équivalente.
la source
Notez également que l'utilisation de la méthode "foreach" dans la question d'origine présente certaines limitations, telles que l'impossibilité de supprimer des éléments de la liste pendant l'itération.
La nouvelle boucle for est plus facile à lire et supprime le besoin d'un itérateur séparé, mais n'est vraiment utilisable que dans les passes d'itération en lecture seule.
la source
removeIf
pourrait être le bon outilUne alternative à forEach afin d'éviter votre "pour chacun":
Variante 1 (simple):
Variante 2 (exécution parallèle (plus rapide)):
la source
for(
formulaire si je veux m'assurer que le même fil est utilisé. J'aime utiliser la forme de flux si j'aime autoriser l'exécution multithread.Il ajoute de la beauté à votre code en supprimant tout l'encombrement de boucle de base. Il donne un look épuré à votre code, justifié ci-dessous.
for
Boucle normale :Utiliser pour chacun:
for-each est une construction sur une collection qui implémente Iterator . N'oubliez pas que votre collection doit implémenter Iterator ; sinon vous ne pouvez pas l'utiliser avec for-each.
La ligne suivante se lit comme " pour chaque TimerTask t dans la liste " .
Il y a moins de risques d'erreurs en cas de pour chacun. Vous n'avez pas à vous soucier de l'initialisation de l'itérateur ou de l'initialisation du compteur de boucle et de sa fin (là où il y a possibilité d'erreurs).
la source
Avant Java 8, vous devez utiliser les éléments suivants:
Cependant, avec l'introduction de Streams dans Java 8, vous pouvez faire la même chose avec beaucoup moins de syntaxe. Par exemple, pour votre,
someList
vous pouvez faire:Vous pouvez en savoir plus sur les flux ici .
la source
The foreach loop, added in Java 5 (also called the "enhanced for loop"), is equivalent to using a java.util.Iterator
Cela ressemblerait à quelque chose comme ça. Très cruel.
Il y a un bon writeup sur chaque dans la documentation Sun .
la source
Comme l'ont dit tant de bonnes réponses, un objet doit implémenter le
Iterable interface
s'il veut utiliser unefor-each
boucle.Je vais publier un exemple simple et essayer d'expliquer d'une manière différente le fonctionnement d'une
for-each
boucle.L'
for-each
exemple de boucle:Ensuite, si nous utilisons
javap
pour décompiler cette classe, nous obtiendrons cet exemple de bytecode:Comme nous pouvons le voir sur la dernière ligne de l'exemple, le compilateur convertira automatiquement l'utilisation de
for-each
mot - clé en utilisationIterator
au moment de la compilation. Cela peut expliquer pourquoi l'objet, qui n'implémente pas leIterable interface
, lancera unException
lorsqu'il essaie d'utiliser lafor-each
boucle.la source
Le Java pour chaque boucle (alias amélioré pour la boucle) est une version simplifiée d'une boucle pour. L'avantage est qu'il y a moins de code à écrire et moins de variables à gérer. L'inconvénient est que vous n'avez aucun contrôle sur la valeur de l'étape et aucun accès à l'index de boucle à l'intérieur du corps de boucle.
Il est préférable de les utiliser lorsque la valeur de l'étape est un simple incrément de 1 et lorsque vous avez uniquement besoin d'accéder à l'élément de boucle actuel. Par exemple, si vous devez parcourir tous les éléments d'un tableau ou d'une collection sans jeter un œil devant ou derrière l'élément actuel.
Il n'y a pas d'initialisation de boucle, pas de condition booléenne et la valeur de l'étape est implicite et est un simple incrément. C'est pourquoi ils sont considérés comme beaucoup plus simples que réguliers pour les boucles.
Amélioré pour les boucles suivent cet ordre d'exécution:
1) corps de boucle
2) répéter à partir de l'étape 1 jusqu'à ce que l'ensemble du tableau ou de la collection ait été traversé
Exemple - tableau entier
La variable currentValue contient la valeur actuelle en boucle dans le tableau intArray. Notez qu'il n'y a pas de valeur de pas explicite - c'est toujours un incrément de 1.
On peut penser que le côlon signifie «dedans». Ainsi, la déclaration de la boucle for améliorée indique: boucle sur intArray et stocke la valeur int du tableau actuel dans la variable currentValue.
Production:
Exemple - String Array
Nous pouvons utiliser la boucle for-each pour parcourir un tableau de chaînes. La déclaration de boucle indique: boucle sur le tableau de chaînes myStrings et stocke la valeur de chaîne actuelle dans la variable currentString.
Production:
Exemple - Liste
La boucle for améliorée peut également être utilisée pour parcourir un java.util.List comme suit:
La déclaration de boucle indique: boucle sur myList List of Strings et stocke la valeur List actuelle dans la variable currentItem.
Production:
Exemple - Définir
La boucle for améliorée peut également être utilisée pour itérer sur un java.util.Set comme suit:
La déclaration de boucle indique: boucle sur mySet Set of Strings et stocke la valeur Set actuelle dans la variable currentItem. Notez que puisqu'il s'agit d'un ensemble, les valeurs de chaîne en double ne sont pas stockées.
Production:
Source: boucles en Java - Ultimate Guide
la source
la source
L'idiome Java for-each ne peut être appliqué qu'aux tableaux ou aux objets de type * Iterable . Cet idiome est implicite car il est vraiment soutenu par un itérateur. L'itérateur est programmé par le programmeur et utilise souvent un index entier ou un nœud (selon la structure des données) pour garder une trace de sa position. Sur le papier, il est plus lent qu'une boucle for régulière, du moins pour les structures "linéaires" comme les tableaux et les listes, mais il fournit une plus grande abstraction.
la source
Ça a l'air fou mais bon ça marche
Cela marche. la magie
la source
Comme beaucoup d'autres réponses le disent correctement, le
for
each
loop
sucre est simplement syntaxique sur le même ancienfor
loop
et le compilateur le traduit dans le même ancien pour la boucle.javac (open jdk) a un commutateur
-XD-printflat
, qui génère un fichier java avec tout le sucre syntaxique supprimé. la commande complète ressemble à ceciPermet donc de retirer le sucre syntaxique
Pour répondre à cette question, j'ai créé un fichier et écrit deux versions de
for
each
, une avecarray
et une autre avec alist
. monjava
dossier ressemblait à ceci.Lorsque j'ai
compiled
ce fichier avec le commutateur ci-dessus, j'ai obtenu la sortie suivante.Vous pouvez voir que, avec l'autre sucre syntaxique (Autoboxing), chaque boucle a été remplacée par une boucle simple.
la source
Itère tous les objets de la table Items.
la source