:: Enseignements :: ESIPE :: E4INFO :: 2025-2026 :: Java Avancé ::
[LOGO]

Examen de Java Avancé 2025 - 2026 - session 2


Le but de ce TP noté est d'implanter une classe Vec qui est une structure de données qui permet l'insertion d'éléments à n'importe quel endroit et offre une vue non-modifiable de type java.util.List.

Vos sources Java produites pendant l'examen devront être placées sous le répertoire EXAM de votre compte ($HOME) (qui est vide dans l'environnement de TP noté). Sinon, elles ne seront pas récupérées.

Tout document papier est proscrit.
La javadoc 25 est disponible à l'adresse : https://igm.univ-mlv.fr/~juge/javadoc-25/.
Les seuls documents électroniques autorisés sont les supports de cours à l'URL http://igm.univ-mlv.fr/~forax/ens/java-avance/cours/pdf/.

Vous avez le droit de lire le sujet jusqu'au bout, cela vous donnera une bonne idée de là où on veut aller !

Exercice 1 - Vec

La classe Vec est une classe qui stocke des éléments non nuls. L'implantation de Vec garanti l'ordre d'insertion.

La classe Vec possède les opérations suivantes :
  • un constructeur qui créé une instance à partir d'éléments passés en paramètre.
  • une méthode d'affichage qui affiche les éléments séparés par des virgules.
  • la méthode add(int index, element) qui ajoute un élément à un index particulier (cela peut être devant tous les éléments, à la fin de tous les éléments ou au milieu).
  • Les méthodes spliterator() et stream() qui renvoie les éléments dans l'ordre d'insertion.
  • la méthode asList() qui renvoie une vue non-modifiable des éléments du Vec. Si le Vec est altéré à postériori, alors la vue ne permet plus d'accéder aux éléments.

Voici un exemple d'utilisation
Vec<String> vec = new Vec<String>("a");
vec.add(1, "b");
vec.add(0, "c");

IO.println(vec);  // c, a, b
IO.println(map.stream().toList());  // [c, a, b]

List<String> view = vec.asList();
IO.println(view);  // [c, a, b]

vec.add(0, "d");
IO.println(view);  // ConcurrentModificationException
     

Dans l'exemple ci-dessus, la vue view est créé sur le vec, si celui-ci change (ici, on ajoute "d" devant), alors la vue devient invalide et il n'est plus possible de lire ses éléments. L'exception ConcurrentModificationException est levée lors que l'on essaye d'accéder aux éléments.

En termes d'implantation, les éléments sont stokés dans un tableau et on utilise un champ size pour savoir combien il y a d'éléments insérés dans le tableau.

Des tests unitaires correspondant à l'implantation sont ici : VecTest.java
Note : comme on utilise les tests unitaires JUnit sans Maven, dans la configuration de votre projet, il faut ajouter la librairie JUnit 5, soit à partir du fichier VecTest.java, en cliquant sur l'annotation @Test et en sélectionnant le quickfix "Fixup project ...", soit en sélectionnant les "Properties" du projet (avec le bouton droit de la souris sur le projet) puis en ajoutant la librairie JUnit 5 (jupiter) au ClassPath.

  1. Dans un premier temps, on veut implanter seulement le constructeur ainsi que la méthode d'affichage.
    A la création, le constructeur doit permettre de passer en paramètres des valeurs séparées par des virgules.
    La méthode d'affichage doit être implantée avec un StringJoiner ou un StringBuilder à votre convenance.
    Attention à ce que votre implantation respected bien le principe d'encapsulation.
    Écrire la classe Vec, son constructeur et sa méthode d'affichage.
    Vérifier que les tests marqués "Q1" passent.

  2. On souhaite changer la méthode d'affichage pour utiliser un stream.
    Mettre en commentaire votre ancien code.
    Écrire une nouvelle implantation de la méthode d'affichage en utilisant un stream.
    Vérifier que les tests marqués "Q2" passent.

  3. On souhaite maintenant pouvoir ajouter des élements en utilisant la méthode add(inde, element).
    Si on insère un élément avant des éléments existants, ceux-ci sont décalés sur droite.
    Si il n'y a plus de place dans le tableau, celui-ci doit doubler sa taille.
    Attention, lors de la création, le tableau doit avoir la même taille que les éléments passés en paramètre, ce n'est que si on utilise la méthode add que le redimensionnement doit être fait.
    Vérifier que les tests marqués "Q3" passent.

  4. Vérifier que le code que vous avez écrit marche si l'on ajoute des éléments avec add(index, element) à un Vec vide au début.
    Vérifier que les tests marqués "Q4" passent.

  5. On souhaite implanter les méthodes spliterator() et stream() qui renvoi tous les éléments du Vec. Pour cela, écrivez votre propre Spliterator sachant que l'on ne s'intéresse qu'à la partie séquentielle.
    Attention, c'est la question qui vaut le plus de points de tout le TP.
    Vérifier que les tests marqués "Q5" passent.
    Il est possible que certains tests ne soient pas présents parmi les tests que l'on vous a fournis. A vous de garantir que votre implantation est correcte.

  6. On peut remarquer que l'on peut créer un stream sur un Vec puis modifier le Vec avant d'utiliser le stream pour faire un parcours. Dans ce cas où l'on essaye d'accéder à un élément alors que le Vec sous-jacent a été modifié, une exception ConcurrentModificationException doit être levée.
    On peut noter que l'on peut facilement savoir si le Vec sous-jacent a été modifié sans pour autant ajouter un ou des champs supplémentaire.
    Modifier votre implantation pour avoir le comportement attendu.
    Vérifier que les tests marqués "Q6" passent.

  7. On souhaite maintenant implanter la méthode asList() qui renvoie une vue non-modifiable du Vec sur lequel asList est appelée.
    Implanter la méthode asList().
    Rappel: L'API de Java (le JDK) possède définie la classe AbstractList pour cela.
    Vérifier que les tests marqués "Q7" passent.

  8. On souhaite qu'accéder aux éléments du Vec à travers la vue ne soit pas possible si le Vec a été modifié après la création de la vue.
    Faite les changements qui s'imposent.
    Vérifier que les tests marqués "Q8" passent.

  9. Enfin, vérifier qu'il n'est pas possible d'accéder aux éléments d'une vue invalidée si on appéle la métode stream sur la vue.
    Vérifier que les tests marqués "Q9" passent.