HMIN215 - Eléments de solutions pour les exercices sur les itérateurs 1 Feu Tricolore Un feu tricolore se compose de trois couleurs (on peut utiliser la classe Color en Java, avec des valeurs comme Color.red). Itérer sur le feu tricolore consiste à parcourir (sans fin a priori) les trois couleurs. Ecrire une classe pour représenter les feux tricolores, un itérateur de feu tricolore et un programme montrant une utilisation. On propose tout d abord une première solution avec une classe interne. public class FeuTricoloreCI implements Iterable<Color> private Color[] tab = Color.green, Color.orange, Color.red; private class IterateurFeuTricoloreCI implements Iterator<Color> private int curseur = 0; public boolean hasnext() return true; public Color next() Color couleurcourante = FeuTricoloreCI.this.tab[curseur]; // ou juste Color couleurcourante = tab[curseur]; curseur ++; if (curseur==3) curseur = 0; return couleurcourante; public Iterator<Color> iterator() return new IterateurFeuTricoloreCI(); public static void main(string [] argv) FeuTricoloreCI f = new FeuTricoloreCI(); Iterator<Color> it = f.iterator(); for (int i=0; i<12; i++) La deuxième solution utilise une classe interne anonyme. public class FeuTricolore implements Iterable<Color> private Color[] tab = Color.green, Color.orange, Color.red; public Iterator<Color> iterator() return new Iterator<Color>() private int curseur = 0;
public boolean hasnext() return true; public Color next() Color couleurcourante = FeuTricolore.this.tab[curseur]; // ou juste Color couleurcourante = tab[curseur]; curseur ++; if (curseur==3) curseur = 0; return couleurcourante; ; public static void main(string [] argv) FeuTricolore f = new FeuTricolore(); Iterator<Color> it = f.iterator(); for (int i=0; i<6; i++) 2 Itérer sur un objet complexe Une feuille de salaire comprend les éléments suivants qui peuvent être représentés par des attributs dans une classe FeuilleSalaire tels que : employeur salarié convention collective nombre d heures payés prélèvements fiscaux : CRDS, CSG, cotisations salariales net à payer... Définir une classe FeuilleSalaire itérable. Un itérateur donnera successivement les valeurs des différents attributs. Cela peut servir par exemple pour écrire une méthode d affichage ou pour récupérer toutes les informations qui sont des nombres (définir de telles opérations en utilisant l itérateur). public class FeuilleSalaire implements Iterable<Object> private String employeur, salarie; private Integer nombreheures; private Double montantnet; public FeuilleSalaire(String employeur, String salarie, Integer nombreheures, Double montantnet) super(); this.employeur = employeur; this.salarie = salarie; this.nombreheures = nombreheures; this.montantnet = montantnet; public String getemployeur() return employeur;
public void setemployeur(string employeur) this.employeur = employeur; public String getsalarie() return salarie; public void setsalarie(string salarie) this.salarie = salarie; public Integer getnombreheures() return nombreheures; public void setnombreheures(integer nombreheures) this.nombreheures = nombreheures; public Double getmontantnet() return montantnet; public void setmontantnet(double montantnet) this.montantnet = montantnet; public Iterator<Object> iterator() return new IterateurFeuilleSalaire(this); public static void main(string[] arg) FeuilleSalaire f = new FeuilleSalaire("IBM","Jean",200,2000.3); for (Object o : f) System.out.println(o); for (Object o : f) if (o instanceof Number) System.out.println(((Number)o).intValue()); Définir un itérateur de feuille de salaire qui retourne successivement chacun des champs de la feuille de salaire. public class IterateurFeuilleSalaire implements Iterator<Object>
private FeuilleSalaire f; private int curseur=0; IterateurFeuilleSalaire(FeuilleSalaire f)this.f=f; public boolean hasnext() return curseur < 4; // ou utiliser f.getclass().getfields().length; public Object next() switch (curseur) case 0: curseur = 1; return f.getemployeur(); case 1: curseur = 2; return f.getsalarie(); case 2: curseur = 3; return f.getnombreheures(); case 3: curseur = 4; return f.getmontantnet(); default: throw new RuntimeException("pas de champ pour cet indice"); Le programme mettant en œuvre une feuille de salaire et un itérateur a été placé dans la classe FeuilleSalaire. 3 Itérateur sur une suite réelle Nous souhaitons représenter des suites réelles, et plus précisément nous nous limitons ici aux suites constantes à partir d un certain rang. On rappelle qu une suite réelle est une application u d une partie de N dans R. On considère ici les suites définies sur N. Une suite est constante à partir d un certain rang s il existe un entier naturel n et un réel a tels que pour tout entier naturel n n, u(n ) = a. Question 1 Ecrivez une classe SuiteConstanteRang pour représenter les suites constantes à partir d un certain rang. On pourra stocker les n 1 premiers éléments dans une ArrayList. Question 2 On rappelle l interface Iterator<E> : public interface Iterator<E> boolean hasnext(); //Returns true if the iteration has more elements. E next() // Returns the next element in the iteration. void remove(); // Removes from the underlying collection the last element // returned by this iterator (optional operation). Ecrivez une classe IterateurSuiteConstanteRang qui permette d itérer sur une suite constante à partir d un certain rang. Un élément a toujours un successeur. L opération remove ne pourra enlever que des éléments entre les rangs 1 et n 1.
Question 3 Rendez la classe SuiteConstanteRang itérable. On rappelle l interface Iterable<E> : public interface Iterable<T> Iterator<T> iterator(); //Returns an iterator over a set of elements of type T. L ensemble de la solution est donné ci-dessous : public class SuiteConstanteRang implements Iterable<Double> private ArrayList<Double> valeurs = new ArrayList<Double>(); private double constante; public SuiteConstanteRang(ArrayList<Double> valeurs, double constante) super(); this.valeurs = valeurs; this.constante = constante; public ArrayList<Double> getvaleurs() return valeurs; public void setvaleurs(arraylist<double> valeurs) this.valeurs = valeurs; public int getrang() return this.valeurs.size(); public double getconstante() return constante; public void setconstante(double constante) this.constante = constante; public Iterator<Double> iterator() return new IterateurSuiteConstante(this); public Double valeur(int n) if (n < this.getrang()) double v=this.getvaleurs().get(n); return v; else return this.getconstante(); public static void main(string[] argv) ArrayList<Double> a = new ArrayList<Double>(); a.add(3.0); a.add(4.0); a.add(5.0); a.add(6.0); a.add(7.0);
SuiteConstanteRang suite = new SuiteConstanteRang(a,8); Iterator<Double> it = suite.iterator(); System.out.println("------avec itérateur"); System.out.println("------avec for"); System.out.println(suite.valeur(i)); it = suite.iterator(); System.out.println("------avec suppression"); for (int i=0; i<4; i++) if (i==2) it.remove(); System.out.println("------après suppression"); it = suite.iterator(); public class IterateurSuiteConstante implements Iterator<Double> private SuiteConstanteRang s; private int indicecourant; public IterateurSuiteConstante(SuiteConstanteRang s) this.s=s; public boolean hasnext() return true; public Double next() Double r = s.valeur(indicecourant); indicecourant+=1; return r; public void remove() if (indicecourant-1 < s.getrang()) s.getvaleurs().remove(indicecourant-1); else System.out.println("retrait sans effet car superieur au rang");
Question 4 Que va écrire le programme suivant et comment l interprétez-vous? Est-ce que cela mérite une modification de ce qui a été précédemment écrit? public static void main(string[] argv) ArrayList<Double> a = new ArrayList<Double>(); a.add(3.0); a.add(4.0); a.add(5.0); a.add(6.0); a.add(7.0); SuiteConstanteRang suite = new SuiteConstanteRang(a,8); Iterator<Double> it = suite.iterator(); for (double e : suite) System.out.println(e); La suite a été définie de manière infinie puisque hasnext retourne toujours vrai, il faut donc veiller à limiter l itération quand on la réalise.