Vector et iterator en java

bonjour,
j’ai un vector d’un tableau de String, voila la syntaxe :

Vector<String[]> vctData = new Vector<String[]>(); 

le tableau de String est contient 3 champs: ID, nom, prenom.

dans une fonction delete, je veux supprimer une ligne (tableau dans mon cas)dans ce vector selon le ID passé en paramètre:


public void deleteI(String clef){
Iterator<String[]> it = vctData.iterator();
			while (it.hasNext()) {
				String id = ((String[]) it.next())[0];
				if(id.equals(clef)){
// ici le code de suppression
                               }

			}
}

le problème c’est comment je fais la suppression?
comment recuperer l’index pour appeler la méthode: vctData.removeElementAt(index); ???

Oula oui ok, alors le problème de la suppression d’un élément d’une collection avec l’utilisation d’un itérateur, c’est la synchronisation des deux…

Techniquement, tu dois utiliser it.remove() (supprime l’élément courant) mais pour un vecor, cette méthode n’est pas supportée et doit être surchargée.

Donc, pourquoi utilise tu un vecteur ? A tu des contraintes de redondance et d’ordre dans ta collection ?
Edité le 29/05/2009 à 09:54

Je me souvenais plus que c’était possible les generics sur les tableaux (genre Iterator<String[]>).

Utilise plutôt une LinkedList qu’un Vector, pour la suppression via Iterator, c’est bien mieux.

non j’ai pas de contraintes, si il y a une autre méthode mieux que :


Vector<String[]> vctData = new Vector<String[]>();  

je vous en prie de me l’expliquer.

je signale aussi que je travaille avec JTable et AbstractTableModel.
j’ajoute une ligne dans le vector et elle s’ajoute dans JTable:

	public void addRow(String ID, String nom, String prenom) {

			String row[] = { ID, nom, prenom };
	
			Iterator<String[]> it = vctData.iterator();
			while (it.hasNext()) {
				String id = ((String[]) it.next())[0];
				if(id.equals(ID))
					return;
			}
			
			vctData.addElement(row);
			fireTableDataChanged();
		}

cette fonction est dans une classe qui hérite de AbstractTableModel

Pas une méthode, une implémentations. Allez, un petit cours bien fait :

www.jmdoudoux.fr…

On a tendance à abandonner Vector car elle est assez lourde.

Et ça change quelque chose ?

Mouais, pour ma part j’aurais extrait ID, nom, prenom dans un bean quelconque pour éviter Vector<String[]> qui en soi n’est pas très parlant. Ensuite j’aurais proposé une implémentation toute bete de hashcode et equals sur ce bean.

Et ainsi, je pourrais utiliser Collection.remove(Object). Après si tu tiens à utiliser Vector, LinkedList, ou MySuperCustomListThatOwnsEverything, libre à toi.

Dans cette démarche, j’ai peut etre oublié quelque chose, c’est pourquoi je recommande d’écrire un test unitaire avant.

Je vais pas contredire ta démarche (surtout pas moi… :slight_smile: ) mais le/les test(s) ne sont pas ceux qui détermineront le type de collection utilisée…

Le premier test, c’est pour vérifier qu’il soit nécessaire de redéfinir hashcode et equals. Après, dans le contexte de son projet, je doute qu’il ait besoin d’écrire des tests pour justifier une implémentation de Collection à une autre (exemple de Vector par rapport à une collection non thread safe).

Après jsais pas trop le sens de ta remarque :neutre:
Sauf si c’est pour le avant : c’est juste mon attirance envers TDD !

Oui c’est là dessus. Depuis le temps que j’essaye de promouvoir le TDD, il serai malvenu de ma part que de te contredire :smiley:

Ok pour le reste.

je peux pas faire un bean, car quand j’ajoute un tableau de Straing dans le vector, cette ligne s’ajoute aussi dans JTable.
JTable a 3 colonnes, quand je fais:


String row[] = { 22, "nom", "prenom" };
vctData.addElement(row);

JTable affiche cette ligne directement.

si je crée un objet, par exemple nommé Personne qui a 3 attributs (id, nom, prenom):

Vector<Personne> vctData = new Vector<Personne>(); 

comment je vais ajouter cet objet a JTable avec un ModelDefault?

public class Personne {
  private String id;
  private String nom;
  private String prenom;

  public String[] toArray() {
    return new String[]{id, nom, prenom};
  }
}

:heink:
Edité le 29/05/2009 à 16:03

Moi je propose autre chose que le TDD, le DDD : Debug Driven Development. C’est tout pareil sauf que tu fous ne mode debug histoire d’être sûr que ça fait ce que c’est censé faire :smiley:

Pour ton problème, crée un TableModel qui renvoie pour 0, 1, 2 le bon champ de ton objet Personne. C’est toujours mieux que de passer par un tableau temporaire (ici, ton new String[]) recrée à chaque fois que tu rafraichis le tableau graphique. ie:

class MonTableModel extends DefaultTableModel {
  ...
  public Object getValueAt(int row, int column) {
    Personne p = this.vector.get(row); // remarque qu'on s'en tape que ça pète une exception parce qu'on est hors index
    switch (column) { // note qu'un enum + Enum<X>.values fera le même boulot en mieux
      case 0: return p.id;
      case 1: return p.nom;
      case 2: return p.prenom;
      default: throw new IllegalArgumentException('column = ' + column);
    }
  }
}