:: Enseignements :: ESIPE :: E3INFO :: 2012-2013 :: Programmation Objet avec Java ::
[LOGO]

Itérateur, Enumération, Mutabilité, Factory method, Varargs


Exercice 1 - Stack

Ecrire une classe Stack qui représente une pile, permettant de stocker des objets, et implémentée par un tableau. Cette classe doit disposer de deux constructeur: l'un ayant un argument, correspondant à la capacité de la pile, et l'autre sans argument qui initialise utilise une capacité par défaut de 10.

  1. Ajouter les méthodes void push(Object o) et Object pop() qui respectivement ajoute un élément au sommet de la pile ou dépile et retourne l'élément au sommet.
  2. Faire en sorte que les variables de type Stack puissent être utilisées dans les structures for-each. Par exemple:
      public static void main(String[] args) {
        Stack s = new Stack();
        s.push("a");
        s.push("b");
        s.push("+");
        for(Object o : s) {
          System.out.println(o);
        }
        s.push("d");
        s.push("e");
        s.push("-");
        s.push("*");
        for(Object o : s) {
          System.out.println(o);
        }
      }
    
  3. Paramétrer la classe par le type des éléments qui y sont stockés (par exemple Stack<String> dans le code ci-dessus).

Exercice 2 - Jeu de cartes

En utilisant la classe Card qui représente une carte et une classe Suit qui répresente une couleur (pique, trèfle, coeur ou carreau), on souhaite écrire une classe Deck (dans le package fr.umlv.card) représentant un jeu de cartes. Cette classe utilisera la classe java.util.ArrayList pour stocker les cartes.


  1. Créer une classe Main et afficher dans le main de celle-ci la valeur de SPADE.
    Rappeler quelle est la différence principale entre un enum en C et un enum en Java ?
  2. Créer une classe Deck. Ecrire un constructeur prenant en paramètre un nombre de cartes par couleur et un tableau de couleurs de cartes (Suit) et créant un jeu de carte. Pour deux cartes par couleur et avec les couleurs CLUB et HEART, le jeu doit contenir quatre cartes [1 of CLUB, 2 of CLUB, 1 of HEART, 2 of HEART] dans cet ordre.
    Pour tester, vous écrirez aussi la fonction d'affichage habituelle.
  3. Modifier le constructeur pour que l'on puisse l'appeler en séparant les couleurs par des virgules. Utiliser la notation varargs (ou ellipsis) pour cela.
    Deck deck = new Deck(2, Suit.CLUB, Suit.HEART);
  4. Utiliser un import static pour pouvoir désigner CLUB et HEART sans les préfixer par Suit ce qui permettra d'écrire le code suivant:
    Deck deck = new Deck(2, CLUB, HEART);
  5. Expliquer pourquoi utiliser un constructeur pour cela n'est pas une bonne idée.
    Modifier le code pour utiliser une factory method à la place.
  6. Pourquoi le constructeur doit maintenant être privée ?
  7. Ecrire une méthode equals qui compare deux Decks (l'ordre des cartes est important).
    Pourquoi doit-on modifier la classe Card ?

Exercice 3 - Mutabilité

  1. En réutilisant la classe Deck, ecrire une méthode getCardList qui renvoie une liste de carte.
    Pourquoi le type de retour de la méthode ne doit pas être ArrayList ?
  2. Le code suivant montre que votre méthode getCardList est mal codée
         Deck deck = ...
         deck.getCardList().remove(0);
        
    Pourquoi ?
    Résoudre le problème en utlisant une copie défensive.
  3. Quelle est le problème de la copie défensive sur une collection ?
    Pourquoi est-il plus efficace d'utiliser la méthode java.util.Collections.unmodifiableList() ?
    Modifier votre code en conséquence.

Exercice 4 - Bataille [A la maison]

  1. Modifier la classe Card pour afficher valets, dames, roi, as (en anglais SVP) à la place de leur valeur numérique.
    Pitié pour le processeur éviter les if ... else imbriqués.
  2. Dans l'exemple suivant, on mélange une liste et le tableau se retrouve mélangé
           String[] array = new String[] { "baz", "foo", "bar" };
           List<String> list = Arrays.asList(array);
           Collections.shuffle(list);
           System.out.println(Arrays.toString(array));
         
    Expliquez ce mystère.
  3. Ecrire dans la classe Deck une méthode shuffle qui renvoie un nouveau Deck dont les cartes sont mélangés.
    Attention, l'ordre des cartes du Deck existant ne doit pas être modifié.
  4. Ecrire dans la classe Deck une méthode split qui après avoir vérifié que le deck contenait un nombre pair de cartes créé deux nouveaux Deck ayant chacun la moitié des cartes.
    Attention, l'ordre des cartes du Deck existant ne doit pas être modifié.
  5. Ecrire une méthode fight qui prend une liste de decks et renvoie une liste de nouveaux decks en ayant appliqué entre eux un tour des règles de la bataille. On considérera qu'en cas de bataille alors qu'il n'y a plus assez de carte, que les cartes sont laissés dans chaque deck.
  6. Ecrire un main de test, qui génére deux decks à partir d'un jeu de 32 cartes, affiche ceux ci, puis affiche tour par tour les decks résultant du jeu de la bataille.
    Attention à vérifier que le jeu ne part pas dans une boucle infinie (rêgle du pat!).