:: Enseignements :: ESIPE :: E4INFO :: 2011-2012 :: Java Avancé ::
[LOGO]

List et Map


Implantation des interfaces List et Map et un peu de réflection.

Exercice 1 - Lists

Le but de cette exercice est d'écrire deux méthode statiques renvoyant des listes particulières à l'intérieur d'une classe fr.umlv.colls.Lists.

  1. Rappeler à quoi servent les classes AbstractList, AbstractSequentialList et RandomAccess.
  2. Ecrire une méthode range qui prend en paramètre un index start et un index end et qui renvoie une liste dont les élements sont les élements compris entre start et end (start et end étant inclues).
    L'astuce est que l'on est pas obligé de stocker les élements entre start et end on peut juste faire en sorte que l'implantation renvoie les élements entre start et end.
    Vérifier que votre implantation est bonne avec le test unitaire suivant: ListsTest.java.
  3. On souhaite maintenant écrire une méthode times qui prend en paramètre un multiplicateur et une liste d'entiers et qui renvoie une nouvelle liste ou chaque entier à la position i a pour valeur l'entier à la position i dans la liste passée en paramètre multiplié par le multiplicateur.
  4. Expliquer pourquoi le test slooowTimes timeout ?
    Comment corriger le problème ?
  5. Implanter la solution retenue.

Exercice 2 - Maps

On cherche maintenant à écrire une classe fr.umlv.colls.Maps. Cette classe possède une méthode statique asMap qui permet de voir n'importe quelle objet sous la forme d'une Map dont les clé sont les propriétés (properties) non statiques de l'objet et les valeurs correspondant aux valeurs des proprités de l'objet.
Un objet définie une propriété s'il possède un getter ou un setter sur cette propriété. Par exemple, la classe java.awt.Point possède une méthode getX, est possède donc une propriété x.

  1. Ecrire dans une classe Main une méthode main qui affiche tous les getters et les setters publique et non statique de la classe java.awt.Color.
  2. Ajouter une method propertyMap qui prend une classe en paramètre et renvoie une Map contenant en clé les nom des propriétés et en valeur un objet Accessor correspondant au couple getter/setter (dont un des deux accesseurs peut être null) publique et non statique).
  3. A quoi sert la classe java.lang.ClassValue ?
    (Aide: Lisez la doc :)
  4. Modifier la méthode propertyMap pour que si on l'appel deux fois avec la même classe la Map renvoyée soit la même (au sens de '==').
  5. Ecrire la méthode asMap dans la classe Maps qui prend en paramètre un objet et renvoie une Map dont les clés sont les propriétés de l'objet et dont les valeurs les valeurs des propriétés de l'objet.
    La Map renvoyé ne devra pas permettre d'ajouter de nouvelle propriété, de supprimer une propriété existant. Par contre, elle devra permettre la consultation des valeurs d'un propriété s'il existe un getter, la modification de la valeur d'une propriété s'il existe un setter.
    Enfin, la méthode put aura une sémantique légèrement modifiée par rapport à la méthode put de l'interface Map car celle-ci renverra toujours null au lieu de renvoyer l'ancienne valeur (car cette valeur n'est pas forcément accessible car le getter peut ne pas exister).
Le test Junit correspondant est MapsTest.java.

Exercice 3 - MethodHandle [A la maison]

On souhaite utiliser la classe MethodHandle du paquetage java.lang.invoke à la place de la classe java.lang.reflect.Field.
Vous pourrez réutiliser les tests JUnit de l'exercice précédent pour valider votre implantation.

  1. Recopier l'implantation de Maps dans Maps2 et changer Maps2 pour utiliser des method handles (MethodHandle) à la place des java.lang.reflect.Method lors des appels aux accesseurs.
  2. Ecrire un test de performance qui test qui entre Maps et Maps2 est le plus efficace lorsque l'on fait une serie d'un million de put/get dans la map retournée.
    On utilisera System.nanoTime pour mesurer le temps d'exécution.