:: Enseignements :: Master :: M1 :: 2024-2025 :: Java Avancé ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) | Examen de Java Avancé 2024 - session 1 |
Le but de ce TP noté est d'implanter une classe Range qui est une liste qui agit
comme une vue pour les valeurs à l'intérieur d'un intervalle [start .. end[.
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.
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 - Range
Un
Range représente l'ensemble des entiers dans l'intervalle entre une valeur
start (comprise) et une valeur
end (non comprise).
Un
Range est une vue non-modifiable qui ne stocke pas les éléments
entre
start et
end mais stocke uniquement les valeurs
start et
end.
Voici un exemple d'utilisation. Pour savoir si un élément est dans l'intervalle,
on peut utiliser la méthode
contains() :
var range = Range.of(2, 5);
System.out.println(range.contains(2)); // true
System.out.println(range.contains(4)); // true
System.out.println(range.contains(5)); // false
La classe
Range possède les méthodes suivantes
Des tests unitaires correspondant à l'implantation sont ici :
RangeTest.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
RangeTest.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.
-
On souhaite que la seule façon de créer un Range soit en utilisant la méthode
of(start, end). On veut de plus, que la classe Range possède une méthode
size (en temps constant), ainsi qu'une méthode permettant l'affichage d'un Range
(pour le format, voir ci-dessus).
Attention, comme la taille (le résultat de la méthode size()) doit être un entier
32 bits positif, il ne doit pas être possible de créer un Range ayant une taille
supérieure à un entier 32 bits positif (Integer.MAX_VALUE).
Déclarer la classe Range ainsi que les méthodes demandées.
Vérifier que les tests unitaires marqués Q1 passent.
Pour la méthode d'affichage, on vous demande d'utiliser un stream.
-
On souhaite pouvoir parcourir tous les éléments d'un Range avec
la boucle for comme ceci
var range = ...
for(var value : range) {
...
}
Faites les changements qui s'imposent.
Vérifier que les tests unitaires marqués Q2 passent.
-
On souhaite que la classe Range soit une liste (de type java.util.List)
non-modifiable.
Faites les changements qui s'imposent.
Vérifier que les tests unitaires marqués Q3 passent.
Rappel : il existe une classe AbstractList.
-
On souhaite pouvoir créer un Stream en utilisant les méthodes
stream() et parallelStream() sur la classe Range.
Dans le cas d'un Stream parallèle, on veut que si l'on a besoin de couper le Stream
en deux, la coupure se fasse en plein au milieu.
Faites en sortes que les méthodes stream et parallelStream
soient implanter correctement.
Vérifier que les tests unitaires marqués Q4 passent.
Attention : start et end ne sont pas forcément positif !
Note : si seul le test rangeIntStreamSortedAlot ne passe pas et que vous ne voyez pas pourquoi,
vous pouvez passer à la suite.
-
On souhaite ajouter une méthode times(function) sur un Range qui renvoie un Gatherer permettant
d'appeler la fonction function avec l'élément courant d'un Stream
et chaque élément du Range.
La méthode times doit fonctionner avec des Stream de n'importe quel type d'objet
et la fonction (function) prise en paramètre sait que les éléments du
Range sont des entiers (primitifs).
Voici un exemple d'utilisation.
record Pair(int v1, int v2) {}
var list = Range.of(0, 2).stream().gather(Range.of(0, 2).times(Pair::new)).toList();
System.out.println(list);
// affiche la liste des Pairs (0, 0), (0, 1), (1, 0) et (1, 1)
Écrire, dans Range, la méthode times.
Vérifier que les tests unitaires marqués Q5 passent.
-
On souhaite ajouter une méthode intStream() qui renvoie les éléments du
Range sous forme d'un Stream de type primitif.
Écrire la méthode intStream().
Vérifier que les tests unitaires marqués Q6 passent.
Rappel : il existe une méthode StreamSupport.intStream(...) !
-
Notre implantation de l'interface List n'est pas finie, en effet,
certaines méthodes de List n'ont pas la bonne complexité.
Changer l'implantation de ces méthodes pour que les tests unitaires
marqués Q7 passent.
-
En fait, la méthode subList a aussi un problème de complexité.
Changer l'implantation de la méthode subList en faisant attention
à ce que deux appels successifs à subList
(range.subList(...).subList(...)) n'aient pas non plus un problème
de complexité.
Vérifier que les tests unitaires marqués Q8 passent.
-
Enfin, on souhaite ajouter une méthode asSet() qui permet de voir
un Range comme un ensemble non-modifiable.
Écrire la méthode asSet.
Vérifier que les tests unitaires marqués Q9 passent.
© Université de Marne-la-Vallée