Participer au site avec un Tip
Rechercher
 

Améliorations / Corrections

Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.

Emplacement :

Description des améliorations :

L'instruction « for each »

Les instructions de boucles Les instructions break et continue



Accès rapide :
La vidéo
L'instruction « for each »
Exemple d'utilisation d'un « for each » sur un tableau
Exemple d'utilisation d'un « for each » sur une collection Java
Utilisation d'Eclipse pour produire un squelette de code pour un « for each »
Utilisation du « for each » et de l'inférence de type sur la déclaration de la variable de boucle
Travaux pratiques

La vidéo

Cette vidéo vous montre comment utiliser la variante "for each" de l'instruction for. Un comparatif avec un for traditionnel vous est proposé. Cette instruction est testée sur les tableaux et sur les collections (classe java.lang.ArrayList).


L'instruction « for each »

L'instruction « for each »

Le premier point important à noter est que Java ne fournit pas de mot clé foreach contrairement à certains autres langages. La boucle « for each » s'introduit en Java via le mot clé for, mais avec une syntaxe légèrement différente de celle utilisée pour le for traditionnel.

Le « for each » permet principalement de parcourir des tableaux ou des collections pour en manipuler tous les éléments. En Java, on distingue les tableaux des collections : voici les principales différences entre ces deux types d'éléments.

Nature de l'élément Exemple Taille Peut contenir des primitifs ?
Tableau int [] intArray = { 10, 20, 30 }; Taille fixe Oui
Collection List<Interger> intCollection = new ArrayList<>(); Taille dynamique Non, mais peut contenir des instances de « wrappers »
les classes enveloppantes (wrapper classes) peuvent contenir des données basées sur des types primitifs. Il existe une classe enveloppante par type primitif : par exemple, la classe java.lang.Integer est associée au type int.

Exemple d'utilisation d'un « for each » sur un tableau

Voici un exemple de parcours d'un tableau Java via l'instruction « for each ». Une à une, les valeurs du tableau seront accessibles via la variable value.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
public class Demo {

    public static void main( String [] args ) {
        
        int [] intArray = { 10, 20, 30, 40, 50 };
        
        for( int value : intArray ) {
            System.out.println( value );
        }
        
    } 
            
}
Exemple d'utilisation sur un tableau

Exemple d'utilisation d'un « for each » sur une collection Java

Voici un exemple de parcours d'une collection Java via l'instruction « for each ». Une à une, les valeurs de la collection seront accessibles via la variable value.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
import java.util.ArrayList;
import java.util.List;

public class Demo {

    public static void main( String [] args ) {
        
        // List<Integer> collection = Arrays.asList( 10, 20, 30, 40, 50, 60 );
        List<Integer> collection = new ArrayList<>();
        collection.add( 10 );
        collection.add( 20 );
        collection.add( 30 );
        collection.add( 40 );
        collection.add( 50 );
        
        for( int value : collection ) {
            System.out.println( value );
        }
        
    } 
            
}
Exemple d'utilisation sur une collection

Utilisation d'Eclipse pour produire un squelette de code pour un « for each »

Encore une fois, un IDE (Integrated Development Environment) peut vous assister dans la production de votre code. Dans ce cours, je pars du principe que vous utilisez Eclipse, mais la procédure ici décrite fonctionne aussi sur de nombreux autres ateliers de développement. Si vous souhaitez obtenir un squelette de code pour une instruction « for each », commencez par taper fore puis appuyez simultanément sur CTRL + Espace. Une liste de propositions vous sera affichée, il ne vous restera plus qu'à y sélectionner le premier (normalement) assistant proposé. Voici une petite capture d'écran issue de l'IDE Eclipse.

Assistance proposée par Eclipse (CRTL+Espace)
dans la capture d'écran proposée, une erreur est affichée. C'est normal : Eclipse corrige votre code au fur et à mesure que vous tapez, sauf que dans notre cas, la ligne n'est pas terminée. Pour Eclipse, le code n'est pas propre. Pour nous, humain, on attendra d'avoir terminé de rédiger notre code pour considérer une éventuelle erreur.

Utilisation du « for each » et de l'inférence de type sur la déclaration de la variable de boucle

Comme nous l'avons déjà vu précédemment dans ce tutoriel Java, depuis la version 10 du Java SE, il est possible d'utiliser le mot clé var pour simplifier l'écriture de vos programmes et déduire le types de vos variables locales automatiquement à partir de leurs valeurs d'initialisation. Cette possibilité peut être aussi utilisée pour le typage de la variable de boucle de votre instruction « for each ». Voici un exemple d'utilisation de cette possibilité.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
import java.util.ArrayList;
import java.util.List;

public class Demo {

    public static void main( String [] args ) {
        
        var collection = Arrays.asList( 10, 20, 30, 40, 50, 60 );
        
        for( var value : collection ) {
            System.out.println( value );
        }
        
    } 
            
}
Utilisation de l'inférence de type pour votre « for each ».

L'inférence de type (la déduction de type) est utilisée à deux endroits dans ce programme. Pour les repérer, cherchez les deux utilisations du mot clé var (ligne 8 et 10).

j'insiste, vous devez avoir un Java SE 10 minimum pour supporter cette possibilité. Veuillez procéder à une mise à jour de votre environnement d'exécution, si nécessaire.

Travaux pratiques

Le sujet

Le but de l'exercice est de définir en mémoire un labyrinthe puis de l'afficher sur la console. Le labyrinthe sera constitué de quatre caractères différents : le caractère '#', représentant un mur, le caractère espace correspondant l'absence de mur, le caractère 'D' correspondant au point de départ et le caractère 'S' indiquant la sortie. Pour définir les données du labyrinthe, je vous propose d'utiliser un tableau, de premier niveau, contenant des sous-tableaux de char. Une fois le labyrinthe définit en mémoire, veuillez l'afficher sur la console en utilisant deux boucles « for each ».

La correction

Voici donc ma correction. Je pense que le code parle de lui-même : notez juste que j'ai utilisé la méthode toCharArray proposée par la classe java.lang.String. Cela me simplifie la vie en permettant la construction d'un tableau de caractères à partir d'une chaîne, franchement plus simple à écrire. L'intérêt de passer à un tableau de tableau de caractères est qu'on pourra ensuite travailler sur chaque emplacement individuel du tableau (par exemple, si l'on cherche à écrire un programme de résolution du labyrinthe, mais on verra cela plus tard).

 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 
public class Demo {

    public static void main( String [] args ) {
        
        // On définit le tableau : la méthode toCharArray transforme
        // une chaîne de caractères en un tableau de caractères.
        char [][] maze = {
            "######################################".toCharArray(),
            "#S     #       #             #       #".toCharArray(),
            "###### # # ### # ########### # ### # #".toCharArray(),
            "#      # # # # # #         # #   #####".toCharArray(),
            "### #### # # # # # # # # # # # #     #".toCharArray(),
            "#      # # # # # # ######### ####### #".toCharArray(),
            "# #### # # # # # #             #     #".toCharArray(),
            "# #    # # # #   # ########### # # # #".toCharArray(),
            "# ###### # # # # # # # # # # # # # # #".toCharArray(),
            "#        #   # #           # #   # #D#".toCharArray(),
            "######################################".toCharArray()
        };

        // On parcourt d'abord les lignes ...
        for( char [] line : maze ) {
            // ... puis ensuite les caractères de chaque ligne.
            for( char cell : line ) {
                System.out.print( cell );
            }
            // On pense à afficher un retour à la fin de la ligne
            System.out.println();   
        }
        
    } 
           
}
Définition et affichage d'un labyrinthe
vous pouvez aussi tenter une variante en replaçant les tableaux Java par des collections Java.


Les instructions de boucles Les instructions break et continue