Java 1.6 a ajouté, à la boucle for tradtionnelle, une boucle "foreach" qui permet de parcourir un objet "conteneur", élément par élément. En fait "foreach" s'écrit "for", plus exactement :

for ( type nom-de-variable : objet ) { ....}

mais bon, on l'appelle quand même foreach....

Je prends l'exemple des intervalles. Ils sont définis par une paire de valeurs (min et max), et quand on les parcourt, on doit récupérer successivement min, min+1, .... jusqu'à max.

Utilisation On initialisera un intervalle en faisant

  Intervalle fourchette = new Intervalle(1,10);

et ensuite on pourra le parcourir

  for (int i : fourchette) {
     System.out.println("i=" + i);
  }

Réalisation : Globalement, la classe Intervalle se présente comme suit

public class Intervalle implements Iterable<Integer> {
       int min, max;
       public Intervalle(int aMin, int aMax) {
           min = aMin;
           max = aMax;
       }
       @Override
       public Iterator<Integer> iterator() {
          // plus de détails, plus loin ....
       }
   }

On déclare qu'elle est itérable, c'est-à-dire que ses instances peuvent être parcourues par un for( : ). Au passage, on précise aussi que le parcours égrène des @Integer@.

Remarquez que la variable de contrôle de ma boucle for est de type int, mais Java se débrouille pour faire les conversions int <-> Integer.

Du coup, la classe Intervalle doit être équipée d'une méthode iterator qui renvoie un itérateur susceptible de fournir des Integer. C'est logique.

Zoom sur la méthode iterator :

public Iterator<Integer> iterator() {
           return new Iterator() {
               int valeurCourante = min;
               @Override
               public boolean hasNext() {
                   return (valeurCourante <= max);
               }
               @Override
               public Integer next() {
                   Integer v = valeurCourante++;
                   return v;
               }
               @Override
               public void remove() {
                   throw new UnsupportedOperationException("Not supported yet.");
               }
           };

Pour faire simple (?), la méthode renvoie un itérateur d'une classe anonyme, avec

  • une variable valeurCourante qui donne la valeur courante de l'itérateur (au début, la première valeur de l'intervalle)
  • une méthode hasNext() pour savoir si il reste des valeurs non "consommées" dans l'intervalle
  • next() qui renvoie la valeur courante, et la fait avancer.
  • ici, on ne se sert pas de remove(), qui permet de « supprimer de la collection sous-jacente à un itérateur la dernière valeur retournée par next(), » la doc dixit. On n'a envie de supprimer des éléments d'un intervalle, donc pas besoin dans cet exemple.

Et bien voila, il n'y a plus qu'à partir en vacances.