W3docs

Boucle for-each (for amélioré) en Java

Parcourez tableaux et collections Java avec la boucle for-each améliorée pour une itération plus simple et plus sûre.

Java 5 a introduit la boucle for améliorée — généralement appelée boucle for-each — pour parcourir chaque élément d'un tableau ou d'une collection sans gérer d'index manuellement. Lorsque vous n'avez pas besoin de l'index, c'est presque toujours le choix le plus lisible.

Syntaxe

for (Type element : iterable) {
  // body — runs once per element
}

Lisez-la ainsi : pour chaque element dans iterable. Le deux-points est obligatoire ; il ne s'agit pas des points-virgules de la boucle for classique.

int[] nums = {10, 20, 30, 40};

for (int n : nums) {
  System.out.println(n);
}

Affiche 10 20 30 40. Pas de compteur, pas de nums.length, pas de nums[i].

Fonctionne sur les tableaux et tout Iterable

La boucle for-each accepte :

  • N'importe quel tableau.
  • Tout ce qui implémente java.lang.Iterable<T> — ce qui inclut toutes les Collection (telles que List, Set et Queue), ainsi que de nombreux autres types du JDK et de bibliothèques.
import java.util.List;

List<String> names = List.of("alice", "bob", "carol");
for (String name : names) {
  System.out.println(name);
}

String text = "abc";
for (char c : text.toCharArray()) {
  System.out.println(c);
}

Notez que String lui-même n'est pas itérable, mais text.toCharArray() produit un tableau, qui lui l'est.

Une Map n'est pas non plus Iterable directement — vous itérez l'une de ses vues à la place : map.keySet(), map.values() ou map.entrySet(). Chacune renvoie un Set ou une Collection, que la boucle for-each prend en charge.

La variable d'élément est une copie

La variable dans l'en-tête de boucle reçoit la valeur de chaque élément. Pour les types primitifs, la modifier ne change pas le tableau :

int[] nums = {1, 2, 3};
for (int n : nums) {
  n *= 10;          // doesn't touch nums
}
System.out.println(nums[0]);   // still 1

Pour les objets, la variable contient une référence, donc appeler des méthodes qui modifient l'objet affectera l'original. Mais réassigner la variable (name = "...";) ne change que la copie locale.

Si vous devez modifier les éléments eux-mêmes, utilisez une boucle indexée :

for (int i = 0; i < nums.length; i++) {
  nums[i] *= 10;
}

Quand vous ne pouvez pas utiliser for-each

Une boucle for-each masque l'index. C'est bien l'intérêt — mais cela signifie aussi que vous ne pouvez pas l'utiliser quand vous avez besoin :

  • De l'index ("item " + i + ": " + value)
  • De supprimer des éléments pendant l'itération (utilisez un Iterator explicite et appelez iterator.remove())
  • De deux collections en parallèle (utilisez des indices)
  • D'itérer en sens inverse ou de sauter des éléments (utilisez un for indexé)

Ne modifiez pas la collection pendant l'itération

Une boucle for-each sur une collection utilise un Iterator en interne. Si vous modifiez la structure de la collection pendant l'itération (ajout ou suppression d'éléments), l'itérateur détecte l'incohérence à l'étape suivante et lève une ConcurrentModificationException :

List<String> names = new ArrayList<>(List.of("alice", "bob"));
for (String n : names) {
  names.remove(n);   // ConcurrentModificationException
}

Pour supprimer en toute sécurité, pilotez la boucle avec un Iterator explicite et appelez son remove() — il maintient l'itérateur et la liste synchronisés :

Iterator<String> it = names.iterator();
while (it.hasNext()) {
  String n = it.next();
  if (n.startsWith("a")) {
    it.remove();      // safe
  }
}

Avec Java 8+, vous pouvez souvent éviter la boucle entièrement : names.removeIf(n -> n.startsWith("a"));.

Avertissement

Lire ou remplacer un élément (list.set(i, x)) pendant une boucle for-each est correct. Seules les modifications structurelles — add et remove sur la collection elle-même — déclenchent l'exception.

Un exemple complet

java— editable, runs on the server

Étape suivante

Lorsque vous avez besoin de quitter une boucle tôt — ou d'ignorer le reste de l'itération en cours — utilisez break et continue.

Pratique

Pratique
Dans une boucle for-each sur un int[], modifier la variable de boucle dans le corps...
Dans une boucle for-each sur un int[], modifier la variable de boucle dans le corps...
Was this page helpful?