IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Collection et Stream Java Discussion :

rendre iterable une Classe contenant un tableau 2D


Sujet :

Collection et Stream Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Janvier 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Janvier 2007
    Messages : 29
    Par défaut rendre iterable une Classe contenant un tableau 2D
    Bonjour à tous.

    J'ai créé une classe Damier, qui contient des Case dans un tableau à deux dimensions.
    Comme on peut faire une boucle foreach sur le tableau, j'en ai déduit qu'il implémentait l'interface Iterable.

    J'aurais aimé que ma classe Damier implémente elle aussi cette interface, afin que ses clients puissent également faire un foreach dessus, au lieu d'avoir à appeler un getTableau(), car je ne souhaite pas que les clients aient accès au tableau directement.

    J'ai donc tenté un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public Iterator iterator()
    {
    return aireJeu.iterator();
    }
    aireJeu étant le tableau 2D de Case.

    Malheureusement, ça ne compile même pas, il me dit que aireJeu, de type Case[][] ne connait pas iterator(). J'ai tenté en mettant un <Case> après le Iterator, même résultat...
    Pourtant, si on peut faire un foreach sur aireJeu, alors aireJeu est Iterable, donc implemente iterator().

    Où me goure-je?

  2. #2
    Membre éprouvé Avatar de bygui
    Homme Profil pro
    PLM/ALM
    Inscrit en
    Avril 2006
    Messages
    133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : PLM/ALM
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 133
    Par défaut
    Bonjour,
    L'iterateur est utilisé pour des objets de types Collection qui étend de la classe Iterable.
    Les collections sont des listes (par exemple tu as Map).

    Tu ne peux pas utilisé la methode iterator() sur n'importe quelle classe.
    Créé toi même tes méthodes de parcours de ton air de jeu (hasnext() et next()).

  3. #3
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,



    Le foreach fonctionne soit avec une classe implémentant Iterable, soit avec un tableau (qui est un type un peu particulier en Java).


    Mais tu peux approcher le même résultat en implémentant ton propre Iterator.
    D'ailleurs il n'est pas difficile de faire un Iterator générique pour les tableaux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    class ArrayIterator<T> implements Iterator<T> {
     
    	private final T[] array;
    	private int index;
     
    	public ArrayIterator(T[] array) {
    		this.array = array;
    		this.index = 0;
    	}
     
    	/**
             * hasNext() renvoit true tant que l'index est plus petit que la taille du tableau
             */
    	public boolean hasNext() {
    		return this.index < this.array.length;
    	}
     
    	/**
             * next() renvoit l'élément suivant.
             * En cas de mauvaise utilisation, les ArrayIndexOutOfBoundsException
             * sont "converties" en NoSuchElementException...
             */
    	public T next() {
    		try {
    			return this.array[this.index++];
    		} catch (ArrayIndexOutOfBoundsException e) {
    			NoSuchElementException error = new NoSuchElementException(e.getMessage());
    			error.initCause(e);
    			throw error;
    		}
    	}
     
    	/**
             * non-supporté
             */
    	public void remove() {
    		// On ne gère pas la suppression :
    		throw new UnsupportedOperationException();
    	}
    }
    Ceta te permet d'avoir un Damier iterable sur ses lignes en cachant le tableau initial :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class Damier implements Iterable<Case[]> {
    	private final Case[][] data = new Case[8][8];
     
    	public Iterator<Case[]> iterator() {
    		return new ArrayIterator<Case[]>(this.data);
    	}
    }
    Par contre comme tu as un tableau à 2 dimensions, cela donne accès aux tableaux de secondes dimensions ce qui pourrait poser problème. Car bien entendu comme pour le foreach sur un tableau [][], cela te renvoi tous les sous tableau [].






    Je ne sais pas ce que tu recherches à faire, mais il pourrait être utile d'avoir directement une iteration sur les éléments du tableau à 2 dimensions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    /**
     * Iterator sur les éléments d'un tableau à deux dimensions :
     */
    class BiArrayIterator<T> implements Iterator<T> {
     
    	private final T[][] array;
    	private int row;
    	private int col;
     
    	public BiArrayIterator(T[][] array) {
    		this.array = array;
    		this.row = 0;
    		this.col = 0;
    	}
     
    	/**
             * hasNext() renvoit true tant que l'index est plus petit que la taille du tableau
             */
    	public boolean hasNext() {
    		return this.row < this.array.length;
    	}
     
    	/**
             * next() renvoit l'élément suivant.
             * En cas de mauvaise utilisation, les ArrayIndexOutOfBoundsException
             * sont "converties" en NoSuchElementException...
             */
    	public T next() {
    		try {
    			T value = this.array[this.row][this.col++];
    			if (this.col >= this.array[this.row].length) {
    				this.col = 0;
    				this.row++;
    			}
    			return value;
    		} catch (ArrayIndexOutOfBoundsException e) {
    			NoSuchElementException error = new NoSuchElementException(e.getMessage());
    			error.initCause(e);
    			throw error;
    		}
    	}
     
    	/**
             * non-supporté
             */
    	public void remove() {
    		// On ne gère pas la suppression :
    		throw new UnsupportedOperationException();
    	}
    }

    Et la classe devient iterable sur des Case et non plus des Case[] :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class Damier implements Iterable<Case> {
    	private final Case[][] data = new Case[8][8];
     
    	public Iterator<Case> iterator() {
    		return new BiArrayIterator<Case>(this.data);
    	}
    }
    a++

  4. #4
    Membre averti
    Inscrit en
    Janvier 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Janvier 2007
    Messages : 29
    Par défaut
    Je voulais bien un itérateur sur les lignes, pour pouvoir traiter ma classe contenant le tableau comme un tableau. Maintenant, ça marche, merci beaucoup pour ce code.

    Mon erreur était de croire que tout ce qui est foreachiable est Iterable. Si j'ai bien compris, un tableau n'est pas Iterable, mais java le rend foreachiable quand même.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 27/11/2006, 23h20
  2. [HTML/JavaScript] Rendre visible une ligne d'un tableau
    Par Jibees dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 20/11/2006, 17h33
  3. Réponses: 7
    Dernier message: 01/09/2006, 14h19
  4. rendre exportable une classe
    Par FamiDoo dans le forum Visual C++
    Réponses: 4
    Dernier message: 09/08/2006, 08h53
  5. Réponses: 10
    Dernier message: 10/01/2006, 14h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo