Considérer:
List<String> someList = new ArrayList<String>();
// add "monkey", "donkey", "skeleton key" to someList
for (String item : someList) {
System.out.println(item);
}
À quoi ressemblerait la boucle équivalente for
sans utiliser la syntaxe for each?
for (Iterator<String> i = someIterable.iterator(); i.hasNext();) {
String item = i.next();
System.out.println(item);
}
Notez que si vous devez utiliser i.remove();
dans votre boucle ou accéder d'une manière ou d'une autre à l'itérateur réel, vous ne pouvez pas utiliser l'idiome for ( : )
, car l'itérateur réel est simplement déduit.
Comme Denis Bueno l'a noté, ce code fonctionne pour tout objet qui implémente l'interface Iterable
.
De même, si le membre de droite de la for (:)
idiom est un objet array
plutôt qu'un objet Iterable
, le code interne utilise un compteur d'index int et vérifie par rapport à array.length
. Voir la spécification du langage Java .
La construction de chaque est également valable pour les tableaux. par exemple.
String[] fruits = new String[] { "Orange", "Apple", "Pear", "Strawberry" };
for (String fruit : fruits) {
// fruit is an element of the `fruits` array.
}
qui est essentiellement équivalent à
for (int i = 0; i < fruits.length; i++) {
String fruit = fruits[i];
// fruit is an element of the `fruits` array.
}
Donc, résumé général:
[nsayer] Ce qui suit est la forme la plus 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 devez utiliser i.remove (); Dans votre boucle, ou accéder d'une manière ou d'une autre à l'itérateur réel, vous ne pouvez pas utiliser l'idiome for (:), car l'Iterator actuel est simplement déduit.
C'est implicite dans la réponse de nsayer, mais il est intéressant de noter que la syntaxe OP pour (..) fonctionnera lorsque "someList" est tout ce qui implémente Java.lang.Iterable - il ne doit pas s'agir d'une liste ou d'une collection de Java.util. Même vos propres types peuvent donc être utilisés avec cette syntaxe.
La foreach
loop , ajoutée dans Java 5 (également appelée "boucle améliorée pour"), équivaut à utiliser un Java.util.Iterator
- c'est le 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 choisi plutôt qu'un itérateur, car il est plus pratique et concis.
_for(int i : intList) {
System.out.println("An element in the list: " + i);
}
_
_Iterator<Integer> intItr = intList.iterator();
while(intItr.hasNext()) {
System.out.println("An element in the list: " + intItr.next());
}
_
Il existe des situations où vous devez utiliser un Iterator
directement. Par exemple, essayer de supprimer un élément en utilisant un foreach
peut (va??) Donner un ConcurrentModificationException
.
foreach
vs. for
: Différences de baseLa seule différence pratique entre for
et foreach
est que, dans le cas d'objets indexables, vous n'avez pas accès à l'index. Exemple lorsque la boucle de base for
est requise:
_for(int i = 0; i < array.length; i++) {
if(i < 5) {
// Do something special
} else {
// Do other stuff
}
}
_
Bien que vous puissiez créer manuellement une variable int d'index distincte avec foreach
,
_int idx = -1;
for(int i : intArray) {
idx++;
...
}
_
il n'est pas recommandé, car variable-scope n'est pas idéal, et la boucle de base for
est simplement le format standard et attendu pour ce cas d'utilisation.
foreach
vs. for
: PerformanceLors de l'accès aux collections, un foreach
est nettement plus rapide que l'accès au tableau de base de la boucle for
. Cependant, lors de l'accès à des tableaux - du moins avec les tableaux primitifs et wrapper-arrays -, l'accès via les index est considérablement plus rapide.
Les index atteignent 23% 40 plus rapidement que les itérateurs lors de l’accès aux tableaux int
ou Integer
. Voici la sortie de la classe testing au bas de cet article, qui additionne les nombres d'un tableau primitive-int de 100 éléments (A est un itérateur, B est un index):
_[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 également exécuté ceci pour un tableau Integer
, et les index sont toujours les grands gagnants, mais seulement entre 18 et 25% plus rapides.
Pour un List
de Integers
, les itérateurs sont clairement gagnants. Il suffit de changer le tableau int dans la classe de test pour:
_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 apportez les modifications nécessaires à la fonction de test (_int[]
_ à _List<Integer>
_, length
à 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 équivalents, mais avec les collections, l'itérateur gagne.
* Ce message est basé sur deux réponses que j'ai écrites sur Stack Overflow:
Quelques informations supplémentaires: Qu'est-ce qui est plus efficace, une boucle for-each ou un itérateur?
J'ai créé cette classe après avoir lu cette question sur le dépassement de pile:
_import Java.text.NumberFormat;
import Java.util.Locale;
/**
<P>{@code Java TimeIteratorVsIndexIntArray 1000000}</P>
@see <CODE><A HREF="https://stackoverflow.com/questions/180158/how-do-i-time-a-methods-execution-in-Java">https://stackoverflow.com/questions/180158/how-do-i-time-a-methods-execution-in-Java</A></CODE>
**/
public class TimeIteratorVsIndexIntArray {
public static final NumberFormat nf = NumberFormat.getNumberInstance(Locale.US);
public static final void main(String[] tryCount_inParamIdx0) {
int testCount;
// Get try-count from a command-line parameter
try {
testCount = Integer.parseInt(tryCount_inParamIdx0[0]);
}
catch(ArrayIndexOutOfBoundsException | NumberFormatException x) {
throw new IllegalArgumentException("Missing or invalid command line parameter: The number of testCount for each test. " + x);
}
//Test proper...START
int[] intArray = new int[] {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};
long lStart = System.nanoTime();
for(int i = 0; i < testCount; i++) {
testIterator(intArray);
}
long lADuration = outputGetNanoDuration("A", lStart);
lStart = System.nanoTime();
for(int i = 0; i < testCount; i++) {
testFor(intArray);
}
long lBDuration = outputGetNanoDuration("B", lStart);
outputGetABTestNanoDifference(lADuration, lBDuration, "A", "B");
}
private static final void testIterator(int[] int_array) {
int total = 0;
for(int i = 0; i < int_array.length; i++) {
total += int_array[i];
}
}
private static final void testFor(int[] int_array) {
int total = 0;
for(int i : int_array) {
total += i;
}
}
//Test proper...END
//Timer testing utilities...START
public static final long outputGetNanoDuration(String s_testName, long l_nanoStart) {
long lDuration = System.nanoTime() - l_nanoStart;
System.out.println("Test " + s_testName + ": " + nf.format(lDuration) + " nanoseconds");
return lDuration;
}
public static final long outputGetABTestNanoDifference(long l_aDuration, long l_bDuration, String s_aTestName, String s_bTestName) {
long lDiff = -1;
double dPct = -1.0;
String sFaster = null;
if(l_aDuration > l_bDuration) {
lDiff = l_aDuration - l_bDuration;
dPct = 100.00 - (l_bDuration * 100.0 / l_aDuration + 0.5);
sFaster = "B";
}
else {
lDiff = l_bDuration - l_aDuration;
dPct = 100.00 - (l_aDuration * 100.0 / l_bDuration + 0.5);
sFaster = "A";
}
System.out.println(sFaster + " faster by " + nf.format(lDiff) + " nanoseconds (" + dPct + "% faster)");
return lDiff;
}
//Timer testing utilities...END
}
_
Voici une réponse qui ne suppose pas la connaissance de 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 à ce qui suit:
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 écrit de manière plus naturelle et moins bruyante sur le plan syntaxique.
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 ensembles qui ne prennent pas en charge l'indexation de tableaux, mais qui implémentent l'interface Java Iterable.
La boucle for-each dans Java utilise le mécanisme d'itérateur sous-jacent. Donc, c'est identique à ce qui suit:
Iterator<String> iterator = someList.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
System.out.println(item);
}
Dans Java 8 fonctionnalités, vous pouvez utiliser ceci:
List<String> messages = Arrays.asList("First", "Second", "Third");
void forTest(){
messages.forEach(System.out::println);
}
First
Second
Third
C'est implicite dans la réponse de nsayer, mais il est intéressant de noter que la syntaxe OP pour (..) fonctionnera lorsque "someList" est tout qui implémente Java.lang.Iterable - il n'est pas nécessaire que ce soit une liste ou une collection de Java.util. Même vos propres types peuvent donc être utilisés avec cette syntaxe.
Comme défini dans JLS , chaque boucle peut avoir deux formes:
Si le type d'expression est un sous-type de Iterable
, la traduction est la suivante:
List<String> someList = new ArrayList<String>();
someList.add("Apple");
someList.add("Ball");
for (String item : someList) {
System.out.println(item);
}
// IS TRANSLATED TO:
for(Iterator<String> stringIterator = someList.iterator(); stringIterator.hasNext(); ) {
String item = stringIterator.next();
System.out.println(item);
}
Si l'expression a nécessairement un type de tableau T[]
, alors:
String[] someArray = new String[2];
someArray[0] = "Apple";
someArray[1] = "Ball";
for(String item2 : someArray) {
System.out.println(item2);
}
// IS TRANSLATED TO:
for (int i = 0; i < someArray.length; i++) {
String item2 = someArray[i];
System.out.println(item2);
}
Java 8 a introduit des flux qui fonctionnent généralement mieux. Nous pouvons les utiliser comme:
someList.stream().forEach(System.out::println);
Arrays.stream(someArray).forEach(System.out::println);
Une syntaxe de boucle foreach est la suivante:
for (type obj:array) {...}
Exemple:
String[] s = {"Java", "Coffe", "Is", "Cool"};
for (String str:s /*s is the array*/) {
System.out.println(str);
}
Sortie:
Java
Coffe
Is
Cool
AVERTISSEMENT: vous pouvez accéder aux éléments d'un tableau à l'aide de la boucle foreach, mais vous ne pouvez PAS les initialiser. Utilisez la boucle originale for
pour cela.
AVERTISSEMENT: vous devez faire correspondre le type du tableau avec l'autre objet.
for (double b:s) // Invalid-double is not String
Si vous voulez éditer des éléments, utilisez la boucle originale for
comme ceci:
for (int i = 0; i < s.length-1 /*-1 because of the 0 index */; i++) {
if (i==1) //1 because once again I say the 0 index
s[i]="2 is cool";
else
s[i] = "hello";
}
Maintenant, si nous jetons s sur la console, nous obtenons:
hello
2 is cool
hello
hello
La construction de boucle Java "for-each" permettra l'itération sur deux types d'objets:
T[]
(tableaux de tout type)Java.lang.Iterable<T>
L'interface Iterable<T>
n'a qu'une méthode: Iterator<T> iterator()
. Cela fonctionne sur les objets de type Collection<T>
parce que l'interface Collection<T>
étend la fonction Iterable<T>
.
Le concept de boucle foreach mentionné dans Wikipedia est mis en évidence ci-dessous:
Cependant, contrairement aux autres constructions de boucles for, les boucles foreach conservent généralement pas de compteur explicite: elles indiquent essentiellement "faites ceci à tout dans cet ensemble", plutôt que "faites ceci x fois". Cela évite le potentiel erreurs off-by-one et rend le code plus simple à lire.
Ainsi, le concept de boucle foreach indique que la boucle n’utilise aucun 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 une erreur unique. Pour décrire le concept général de cette erreur unique, prenons un exemple de boucle à parcourir dans une liste à l’aide d’index.
// In this loop it is assumed that the list starts with index 0
for(int i=0; i<list.length; i++){
}
Mais supposons que si la liste commence par l’indice 1, cette boucle lève une exception car elle ne trouve aucun élément à l’indice 0 et cette erreur est appelée erreur off-by-one. Donc, pour éviter cette erreur "one-by-one", le concept de boucle foreach est utilisé. Il peut aussi y avoir d’autres avantages, mais c’est à mon sens le principal concept et l’avantage d’utiliser une boucle foreach.
Notez également que l'utilisation de la méthode "foreach" dans la question initiale 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 elle n'est vraiment utilisable que dans les passes d'itération en lecture seule.
En utilisant les anciennes versions de Java, y compris Java 7
, vous pouvez utiliser la boucle foreach
comme suit.
List<String> items = new ArrayList<>();
items.add("A");
items.add("B");
items.add("C");
items.add("D");
items.add("E");
for(String item : items){
System.out.println(item);
}
Voici la toute dernière façon d’utiliser la boucle foreach
dans Java 8
(boucle une liste avec forEach
+ expression lambda ou référence de méthode)
//lambda
//Output : A,B,C,D,E
items.forEach(item->System.out.println(item));
//method reference
//Output : A,B,C,D,E
items.forEach(System.out::println);
Pour plus d'informations, consultez ce lien.
Voici une expression équivalente.
for(Iterator<String> sit = someList.iterator(); sit.hasNext(); ) {
System.out.println(sit.next());
}
Une alternative à forEach afin d'éviter votre "pour chaque":
List<String> someList = new ArrayList<String>();
Variante 1 (nature):
someList.stream().forEach(listItem -> {
System.out.println(listItem);
});
Variante 2 (exécution parallèle (plus rapide)):
someList.parallelStream().forEach(listItem -> {
System.out.println(listItem);
});
Dans Java 8, ils ont introduit forEach. En utilisant cette liste, les cartes peuvent être mises en boucle.
Boucle une liste en utilisant pour chacun
List<String> someList = new ArrayList<String>();
someList.add("A");
someList.add("B");
someList.add("C");
someList.forEach(listItem -> System.out.println(listItem))
ou
someList.forEach(listItem-> {
System.out.println(listItem);
});
Boucle une carte en utilisant pour chacun
Map<String, String> mapList = new HashMap<>();
mapList.put("Key1", "Value1");
mapList.put("Key2", "Value2");
mapList.put("Key3", "Value3");
mapList.forEach((key,value)->System.out.println("Key: " + key + " Value : " + value));
ou
mapList.forEach((key,value)->{
System.out.println("Key : " + key + " Value : " + value);
});
Il ajoute de la beauté à votre code en supprimant tout l'encombrement en boucle de base. Cela donne à votre code une apparence propre, justifiée ci-dessous.
boucle normale for
:
void cancelAll(Collection<TimerTask> list) {
for (Iterator<TimerTask> i = list.iterator(); i.hasNext();)
i.next().cancel();
}
en utilisant pour-each:
void cancelAll(Collection<TimerTask> list) {
for (TimerTask t : list)
t.cancel();
}
for-each est une construction sur une collection qui implémente Iterator. Rappelez-vous que votre collection doit implémenter Iterator; sinon vous ne pouvez pas l'utiliser avec pour chacun.
La ligne suivante est lue comme " pour chaque tâche de minuterie dans la liste. "
for (TimerTask t : list)
Il y a moins de chance d'erreurs en cas de pour-chacun. Vous n'avez pas à vous soucier d'initialiser l'itérateur ou d'initialiser le compteur de boucle et de le terminer (s'il y a une marge d'erreur possible).
Cela ressemblerait à quelque chose comme ça. Très cruel.
for (Iterator<String> i = someList.iterator(); i.hasNext(); )
System.out.println(i.next());
Il y a une bonne écriture sur pour chaque dans le documentation Sun .
Avant Java 8, vous devez utiliser les éléments suivants:
Iterator<String> iterator = someList.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
System.out.println(item);
}
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:
someList.stream().forEach(System.out::println);
Vous pouvez en savoir plus sur les flux ici .
Comme tant de bonnes réponses l'ont dit, un objet doit implémenter le Iterable interface
s'il veut utiliser une boucle for-each
.
Je vais poster un exemple simple et essayer d’expliquer différemment le fonctionnement d’une boucle for-each
.
Exemple de boucle for-each
:
public class ForEachTest {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("111");
list.add("222");
for (String str : list) {
System.out.println(str);
}
}
}
Ensuite, si nous utilisons javap
pour décompiler cette classe, nous obtiendrons cet exemple de code secondaire:
public static void main(Java.lang.String[]);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=4, args_size=1
0: new #16 // class Java/util/ArrayList
3: dup
4: invokespecial #18 // Method Java/util/ArrayList."<init>":()V
7: astore_1
8: aload_1
9: ldc #19 // String 111
11: invokeinterface #21, 2 // InterfaceMethod Java/util/List.add:(Ljava/lang/Object;)Z
16: pop
17: aload_1
18: ldc #27 // String 222
20: invokeinterface #21, 2 // InterfaceMethod Java/util/List.add:(Ljava/lang/Object;)Z
25: pop
26: aload_1
27: invokeinterface #29, 1 // InterfaceMethod Java/util/List.iterator:()Ljava/util/Iterator;
Comme nous pouvons le voir à la dernière ligne de l'exemple, le compilateur convertira automatiquement l'utilisation du mot clé for-each
en une utilisation de Iterator
au moment de la compilation. Cela peut expliquer pourquoi l’objet, qui n’implémente pas le Iterable interface
, lève un Exception
lorsqu’il essaie d’utiliser la boucle for-each
.
public static Boolean Add_Tag(int totalsize)
{ List<String> fullst = new ArrayList<String>();
for(int k=0;k<totalsize;k++)
{
fullst.addAll();
}
}
Le Java pour chaque boucle (aka amélioré pour la boucle) est une version simplifiée d'une boucle for. 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 la boucle à l'intérieur du corps de la boucle.
Elles sont mieux utilisées lorsque la valeur de pas est un simple incrément de 1 et que vous n’avez besoin que d’un accès à l’élément de boucle en cours. Par exemple, si vous devez parcourir tous les éléments d'un tableau ou d'une collection sans jeter un coup d'oeil en avant ou derrière l'élément en cours.
Il n'y a pas d'initialisation de boucle, pas de condition booléenne et la valeur de pas est implicite et est un incrément simple. C’est pourquoi ils sont considérés beaucoup plus simples que les boucles classiques.
Les boucles for améliorées suivent cet ordre d'exécution:
1) corps de la boucle
2) répéter à partir de l'étape 1 jusqu'à ce que tout le tableau ou la collection soit traversé
Exemple - Tableau entier
int [] intArray = {1, 3, 5, 7, 9};
for(int currentValue : intArray) {
System.out.println(currentValue);
}
La variable currentValue conserve la valeur actuelle en boucle dans le tableau intArray. Notez qu’il n’ya pas de valeur de pas explicite - c’est toujours un incrément de 1.
On peut penser que le côlon signifie "dans". Ainsi, les états améliorés de déclaration de boucle: boucle sur intArray et stocke la valeur int actuelle du tableau dans la variable currentValue.
Sortie:
1
3
5
7
9
Exemple - Tableau de chaînes
Nous pouvons utiliser la boucle for-each pour parcourir un tableau de chaînes. La déclaration de boucle indique: boucle sur le tableau myStrings String et stocke la valeur actuelle de la chaîne dans la variable currentString.
String [] myStrings = {
"alpha",
"beta",
"gamma",
"delta"
};
for(String currentString : myStrings) {
System.out.println(currentString);
}
Sortie:
alpha
beta
gamma
delta
Exemple - Liste
La boucle for améliorée peut également être utilisée pour parcourir une Java.util.List comme suit:
List<String> myList = new ArrayList<String>();
myList.add("alpha");
myList.add("beta");
myList.add("gamma");
myList.add("delta");
for(String currentItem : myList) {
System.out.println(currentItem);
}
La déclaration de boucle indique: boucle sur la liste de chaînes myList et stocke la valeur de liste actuelle dans la variable currentItem.
Sortie:
alpha
beta
gamma
delta
Exemple - Définir
La boucle for améliorée peut également être utilisée pour effectuer une itération sur un fichier Java.util.Set comme suit:
Set<String> mySet = new HashSet<String>();
mySet.add("alpha");
mySet.add("alpha");
mySet.add("beta");
mySet.add("gamma");
mySet.add("gamma");
mySet.add("delta");
for(String currentItem : mySet) {
System.out.println(currentItem);
}
La déclaration de boucle indique: boucle sur l'ensemble de chaînes mySet et stocke la valeur actuelle de Set 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.
Sortie:
alpha
delta
beta
gamma
Source: Boucles dans Java - Guide ultime
Le Java de chaque idiome ne peut être appliqué qu'à des tableaux ou des objets de type * Iterable. Cet idiome est implicite comme il est véritablement soutenu par un itérateur. L'Iterator est programmé par le programmeur et utilise souvent un index entier ou un nœud (en fonction de la structure de données) pour garder une trace de sa position. Sur le papier, il est plus lent qu'une boucle for régulière, au moins pour les structures "linéaires" telles que les tableaux et les listes, mais il fournit une plus grande abstraction.
Cela a l'air fou mais bon ça marche
List<String> someList = new ArrayList<>(); //has content
someList.forEach(System.out::println);
Cela marche. Magique