:: Enseignements :: Master :: M1 :: 2020-2021 :: 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> {
        int add(E element, int count);
        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 create 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. Ajoutez une méthode forEach dans l'interface Bag qui prend une fonction qui prend un élément et renvoie void et appelle celle-ci pour chaque élément présent dans le Bag.
    Donc si un élément est présent deux fois dans le Bag, la fonction doit être appelée deux fois.
    Attention à ce que la signature de forEach soit la plus "générique" possible.
  4. É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.
  5. 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 ?
  6. 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 ?
  7. Écrivez une méthode asCollection qui permet de voir un Bag comme une collection non modifiable.
    Note: il existe une classe AbstractCollection !
  8. Vérifiez que les tests BagTest.shouldNotRecreateTheWholeBagWithAsCollection et BagTest.shouldBeEffcientWhenUsingContainsFromAsCollection sont corrects. Sinon modifiez votre implantation.
  9. Dans l'interface Bag, ajoutez une méthode createOrderedByInsertion permettant de créer un Bag vide dont les éléments seront triés par ordre d'insertion. Puis ajoutez une méthode createOrderedByComparator() 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.
  10. Enfin, toujours dans l'intérface Bag, écrire une méthode createOrderedByElement qui présuppose que les élements sont Comparable et donc possède déjà un ordre de comparaison et renvoie une implantation de Bag dont les éléments seront triés par l'ordre défini par leurs méthodes compareTo.
    Note: cette nouvelle méthode devra utiliser la méthode createOrderedByComparator et vous pouvez trouverez le comparateur dont vous avez besoin dans la classe Comparator ou l'écrire vous même.