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.