:: Enseignements :: Master :: M1 :: 2019-2020 :: Java Avancé ::
[LOGO]

L'affaire est dans le sac



Exercice 1 - Bag

Le but de cet exercice est d'implanter un Bag qui est une structure de données qui associe à chaque élément le nombre de fois que cet élément a été ajouté dans le Bag. L'interface de fr.umlv.bag.Bag est la suivante
      public interface Bag<E> {
        public int add(E element, int count);
        public int count(Object element);
      }
    
  • La méthode add permet d'ajouter count fois un element dans le Bag et renvoie le nombre de fois que l'élément est présent dans le Bag ; count doit être strictement positif et element pas null.
  • La méthode count renvoie le nombre de fois que element est présent dans le Bag, 0 si element n'est pas présent dans le Bag.
Le test JUnit est ici BagTest.java.


  1. Expliquez pourquoi count prend un Object en paramètre, et pas un E ?
  2. Écrivez une méthode createSimpleBag dans l'interface Bag qui permet de créer une implantation de Bag, appelée BagImpl dans un autre fichier utilisant une table de hachage pour associer un compteur à chaque élément.
  3. Rappeler la règle concernant l'utilisation des méthodes publiques d'une classe dans le code de cette classe, et vérifier que ce que vous avez écrit la respecte.
  4. Ajoutez une méthode forEach dans l'interface Bag qui prend un consommateur en paramètre (une fonction qui prend un élément et renvoie void) et appelle celui-ci pour chaque élément présent dans le Bag.
    Donc si un élément est présent deux fois dans le Bag, le consommateur doit être appelé deux fois.
    Attention à ce que la signature de forEach soit la plus "générique" possible.
  5. Écrivez une méthode iterator qui renvoie un itérateur sur les éléments du Bag. Comme pour la méthode forEach si un élément est présent deux fois dans le bag, la méthode next de l'itérateur devra retourner l'élément deux fois.
    On ne vous demande pas d'implanter la méthode remove de l'itérateur.
  6. Rappeler quelle est la particularité de la Collection renvoyée par la méthode Collections.nCopies().
    En fait, il est tout à fait possible de créer un Iterator à partir d'un Stream. Sachant cela et en utilisant Collections.nCopies(), écrire une deuxième version de l'itérateur qui fabrique un stream et utilise l'itérateur de ce stream.
    Comparer les performances par rapport à la version que vous avez précédemment écrite.
    Quelle est la meilleure implantation ?
  7. Comment faire pour pouvoir utiliser une instance de Bag dans une boucle "for each in" for(:) ?
    Pourquoi le code de la méthode forEach n'est plus nécessaire ?
  8. Écrivez une méthode asCollection qui permet de voir un Bag comme une collection non modifiable.
    Note: il existe une classe AbstractCollection !
  9. Vérifiez que les tests BagTest.shouldNotRecreateTheWholeBagWithAsCollection et BagTest.shouldBeEffcientWhenUsingContainsFromAsCollection sont corrects. Sinon modifiez votre implantation.
  10. Ajoutez une méthode createOrderedByInsertionBag à l'interface Bag permettant de créer un Bag vide dont les éléments seront triés par ordre d'insertion. Puis ajoutez une méthode createOrderedByElementBag() prenant un Comparator en paramètre et créant un Bag dont les éléments seront triés par l'ordre défini par le comparateur.
  11. Écrire une méthode createOrderedByElementBagFromCollection qui prend en paramètre une collection dont les éléments sont comparables et créé un Bag qui stocke les éléments de la collection dans le Bag de telle façon que les éléments sont triés suivant l'ordre du du Comparable implémenté par les éléments de la collection.
    Note: cette nouvelle méthode devra utiliser la méthode createOrderedByElementBag. Vous trouverez le comparateur dont vous avez besoin dans la classe Comparator.