web-dev-qa-db-fra.com

Comment fonctionne la boucle Java 'pour chaque'?

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?

1414
Jay R.
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 .

1117
nsayer

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.

[Denis Bueno]

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.

473
Mikezx6r

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.

pour chaque

_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 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 base

La 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: Performance

Lors 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.

Synchronisation de la différence entre l'itérateur et l'accès à l'index pour les primitives int-arrays

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 les collections, les itérateurs sont plus rapides que les index

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?

La classe de test complète

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;

/**
   &lt;P&gt;{@code Java TimeIteratorVsIndexIntArray 1000000}&lt;/P&gt;

   @see  &lt;CODE&gt;&lt;A HREF=&quot;https://stackoverflow.com/questions/180158/how-do-i-time-a-methods-execution-in-Java&quot;&gt;https://stackoverflow.com/questions/180158/how-do-i-time-a-methods-execution-in-Java&lt;/A&gt;&lt;/CODE&gt;
 **/
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

}
_
144
aliteralmind

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.

126
MRocklin

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);
}
37
toluju

Dans Java 8 fonctionnalités, vous pouvez utiliser ceci:

List<String> messages = Arrays.asList("First", "Second", "Third");

void forTest(){
    messages.forEach(System.out::println);
}

Sortie

First
Second
Third
23
Jrovalle

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.

23
EfForEffort

Comme défini dans JLS , chaque boucle peut avoir deux formes:

  1. 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);
    }
    
  2. 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);
22
i_am_zero

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
22
PrivateName

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>.

20
Ryan Delucchi

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.

15
oneConsciousness

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.

9
billjamesdev

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.

https://www.mkyong.com/Java8/Java-8-foreach-examples/

9
Dulith De Costa

Voici une expression équivalente.

for(Iterator<String> sit = someList.iterator(); sit.hasNext(); ) {
    System.out.println(sit.next());
}
9
Hank

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);
});
8
vivekkurien

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).

7
Manohar

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 .

6
Pete

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 .

6
Girish Pandey

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.

5
L Joey
public static Boolean Add_Tag(int totalsize)
{ List<String> fullst = new ArrayList<String>();
            for(int k=0;k<totalsize;k++)
            {
              fullst.addAll();
            }
}
3
Santhosh Rajkumar

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

3
gomisha

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.

2
WIll

Cela a l'air fou mais bon ça marche

List<String> someList = new ArrayList<>(); //has content
someList.forEach(System.out::println);

Cela marche. Magique

1
Rei Brown