Les listes/tableaux dynamiques
Lire la section 3 (les vecteurs dynamiques - classe ArrayList) du chapitre 22 (les collections et les algorithmes),
à l'exclusion de la section 3.6.
Les classes ArrayList, Iterator, etc. se trouvent dans la paquet java.util
Pour les utiliser, pensez à ajouter "import java.util.Classe;" dans votre code, e.g. :
import java.util.ArrayList;
import java.util.Iterator;
ou, pour importer toutes les classes du paquet :
import java.util.*;
On avait vu jusqu'ici les tableaux à indices (e.g. le tableau de type Token[] de la classe Sentence).
Ces tableaux sont statiques, i.e. ils ont une taille fixe :
lors de la création d'un tel tableau, la taille (le nombre d'éléments que le tableau peut recevoir)
doit être indiquée à l'avance. Or, on ne connaît pas toujours cette donnée a priori.
Les ArrayList sont des tableaux dynamiques auxquels ont peut ajouter et supprimer des éléments
au fur et à mesure des besoins.
On peut déclarer des listes d'un type donné,
e.g. des listes de dépendances syntaxiques :
// ici, déclaration et construction préalable de diverses instances de Token (verbToken, nounToken, etc.)
ArrayList<SyntacticDepency> listeDeps = new ArrayList<SyntacticDepency>();
SyntacticDepency syntDep = new SyntacticDepency();
syntDep.setGovernor(verbToken);
syntDep.setDependent(nounToken);
syntDep.setDepLabel("obj");
listeDeps.add (syntDep);
// à noter : syntDep est déclarée comme une SyntacticDepency
// on peut lui affecter une instance d'une classe dérivée (en l'occurrence, IndirectDependency)
syntDep = new IndirectDepency();
syntDep.setGovernor(noun1Token);
syntDep.setDependent(noun2Token);
syntDep.setDepLabel("prep");
// syntDep est déclarée de type SyntacticDependency :
// on ne peut donc pas écrire syntDep.setPivot(prepToken);
// En effet, getPivot() n'est pas une méthode de SyntacticDependency.
// Pour pouvoir invoquer une méthode propre à IndirectDependency (ici : getPivot)
// il faut "rappeler" explicitement que syntDep rérérence une instance de cette classe
// par un cast (transtypage)
((IndirectDependency) syntDep).setPivot(prepToken);
listeDeps.add (syntDep);
// ajout d'autres dépendances
Quand on itère sur une telle liste, on sait (mieux : Java le sait aussi)
que chaque objet est une instance de la classe SyntacticDepency
(ou d'une classe dérivée).
for (int i = 0; i < listeDeps.size(); i++)
{
SyntacticDepency currentDep = listeDeps.get(i);
System.out.println(currentDep.getTextRepresentation());
}
On peut également travailler avec des listes "non typées"
(cette appelation est un abus de langage). Avant la version 1.5 de Java,
on ne précisait pas le type d'éléments contenus dans la liste :
ArrayList maListe = new ArrayList ();
En réalité, les éléments qui seront potentiellement contenus dans cette liste sont typés,
mais ils sont de type Object (ou l'une de ses classes dérivées, c'est à dire toutes les classes
fournies par l'API et toutes les classes que vous allez créer).
Pour une telle liste, on écrit aujourd'hui explicitement qu'elle est destinée à
recevoir des instances de la classe Object :
ArrayList<Object> maListe = new ArrayList<Object> ();
On peut ainsi ajouter toute sorte d'objets dans une telle liste,
mais attention : lorsqu'on récupère un objet contenu dans la liste,
il est (pour Java) de type Object.
Pour utiliser des méthodes spécifiques à un classe moins générique,
c'est à vous de savoir de quelle classe est l'objet et de le transtyper (pour rassurer Java).
Il existe un mot-clé pour tester si un objet est une instance d'une classe donnée : instanceof.
Le test "if (obj insanceof NomClasse)" renvoie true si obj est une instance de la classe,
et false sinon. Exemple :
ArrayList<Object> maListe = new ArrayList<Object> ();
maListe.add (new Integer (5));
maListe.add ("deuxième élément");
maListe.add (syntDep); // instance de SyntacticDependancy déclarée plus haut
maListe.add (nounToken); // instance de Token déclarée plus haut
for (int i = 0; i < maListe.size(); i++)
{
Object currentObj = maListe.get(i); // on récupère une instance de Object
if (currentObj instanceof SyntacticDependancy)
System.out.println(((SyntacticDependancy) currentObj).getTextRepresentation()); // transtypage pour pouvoir invoquer une methode de SyntacticDependancy
else
System.out.println(currentObj.toString ());
}