Série 5 – Listes
Introduction
Le but de cette série, la première du mini-projet collections, est de terminer la mise en œuvre des deux types de listes vus au cours, à savoir les tableaux-listes et les listes chaînées.
Pour démarrer, nous vous fournissons une archive Zip contenant la totalité du code écrit durant le cours, ainsi qu'une version améliorée des tests.
Exercice 1 – tableaux-listes
Le fichier ArrayList.java
fourni contient la mise en œuvre partielle des tableaux-listes écrite durant le cours. Elle est encore incomplète, comme on peut le constater en exécutant la classe de test ArrayListTest
. Le but de ce premier exercice est de terminer cette mise en œuvre afin que la totalité des tests s'exécutent sans erreur.
Méthode set
Pour commencer, écrivez la méthode set
et vérifiez que les deux méthodes de test qui l'utilisent s'exécutent sans problème.
Méthode toString
Cela fait, ajoutez à votre classe une méthode toString
redéfinissant la méthode toString
de Object
et produisant la représentation textuelle de la liste. Celle-ci doit être composée d'un crochet ouvrant, de la représentation textuelle des éléments de la liste, dans l'ordre et séparés les uns des autres par une virgule, puis d'un crochet fermant. Ainsi, la représentation textuelle d'une liste vide est la chaîne []
tandis que celle d'une liste contenant les entiers de 1 à 3 dans l'ordre est [1,2,3]
.
Pour définir cette méthode, il est conseillé d'utiliser l'itérateur de la liste, le code sera ainsi utilisable tel quel dans la classe LinkedList
ou toute autre mise en œuvre des listes. De plus, en utilisant judicieusement la méthode hasNext
il est facile de savoir si une virgule doit être ajoutée à la chaîne en construction ou non.
Comme vous le savez, les chaînes Java sont immuables, mais fort heureusement le bâtisseur StringBuilder
permet de les construire petit-à-petit.
Une fois la méthode toString
écrite, vérifiez que les deux méthodes de test qui l'utilisent s'exécutent maintenant sans problème.
Exceptions de la méthode remove
L'itérateur que nous avons défini en classe n'est pas tout à fait terminé puisque sa méthode remove
ne lève pas d'exception en cas d'appel erroné.
La documentation de la méthode remove
de l'interface Iterator
précise que l'exception IllegalStateException
doit être levée si la méthode remove
est appelée avant que la méthode next
n'ait été appelée, ou si elle a déjà été appelée une fois après le dernier appel à next
.
Modifiez la classe ALIterator
afin qu'elle se comporte ainsi, et vérifiez ensuite que la totalité des méthodes de test de la classe ArrayListTest
passent sans erreur.
Conseil : il peut être judicieux d'ajouter à l'itérateur un champ booléen nommé p.ex. canRemove
qui est vrai si et seulement si un appel à remove
est valide.
Exercice 2 – listes chaînées
Le fichier LinkedList.java
fourni contient la mise en œuvre partielle des listes doublement chaînées avec nœud d'en-tête écrite durant le cours. Elle est encore incomplète, comme on peut le constater en exécutant la classe de test LinkedListTest
. Le but de ce second exercice est de terminer cette mise en œuvre.
Méthode set
Tout comme pour l'exercice précédent, écrivez la méthode set
puis vérifiez que les méthodes de test qui s'y rapportent fonctionnent.
Itérateur
Ajoutez un itérateur à la classe LinkedList
. Pour ce faire, il faut procéder comme pour les tableaux-listes, si ce n'est que la technique d'itération doit être différente et se baser sur les nœuds et pas sur la méthode get
, au vu de la complexité de cette dernière pour les listes chaînées.
Comme illustré au cours, un itérateur sur les listes doublement chaînées circulaires avec nœud d'en-tête doit stocker deux informations au sujet de la liste qu'il parcourt : une référence vers le nœud d'en-tête, pour savoir quand la fin de la liste a été atteinte, et une référence vers le nœud dont la valeur sera retournée par le prochain appel à next
.
Méthode toString
Une fois l'itérateur défini, l'ajout d'une méthode toString
devient trivial puisqu'il suffit de copier la méthode toString
de la classe ArrayList
(pour peu, bien entendu, que cette dernière ait été exprimée en termes de l'itérateur, comme cela était suggéré à l'exercice précédent). Faites cette copie et vérifiez que les tests se rapportant à la méthode toString
passent sans erreur.
Exercice 3 – listes itérables
Pour terminer, faites en sorte qu'il soit possible de parcourir vos listes au moyen de la boucle for-each. Comme expliqué dans le cours, il suffit pour cela qu'elles implémentent l'interface Iterable
.
Une fois la modification faite, vérifiez que vous pouvez bien parcourir l'une de vos listes au moyen de la boucle for-each en ajoutant une méthode de test à la classe ListTest
.