Lab 13

advertisement
CSC 205
Java Programming II
2/8/2016
Lab 13
Using Java Collection API
After this lab, you should be:
 Able to use methods of the java.util.Collections class to perform sort,
shuffle, and swap operations on list objects
 Familiar with several Java interfaces such as Iterator, Comparable, and
Comparator
 Able to use TreeMap and TreeSet to store collections of objects
Part 1 – Manipulating Lists Using The java.util.Collections Class
The java.util.Collections class provides a number of static methods that can be
used to manipulate a List object:
public static void shuffle(List list)
Randomly permutes the specified list using a default
source of randomness.
public static void sort(List list)
Sorts the specified list into ascending order, according to
the natural ordering of its elements.
public static void sort(List list, Comparator c)
Sorts the specified list according to the order induced by
the specified comparator.
public static void swap(List list, int i, int j)
Swaps the elements at the specified positions in the
specified list.
We will use a few simple applications to demonstrate how these methods can be used in
simulating card games. The Card class, which is similar to the one introduced in King’s
text is used extensively in the following tasks.
1.1 Sample code: DeckTest.java. This program intends to generate a deck of cards
and then shuffle it into a random order. Notice that this class and the Card class
belong to the card package.
a. Compile and run this program. The order of cards in the deck doesn’t change
after the dummy shuffle method is invoked.
b. Implement the shuffle method by using the shuffle method of the
Collections class as follows
Collections.shuffle(cards);
Compile and run the program to see the order change.
c. Implement another shuffle method by using the swap method of the
Collections class. The new method will take an int value as parameter,
which specifies the desired number of swap operations. Add the following
statements to the new method
int i = Card.randomInt(0, cards.size()-1);
int j = Card.randomInt(0, cards.size()-1);
Collections.swap(cards, i, j);
Lab 13-1
CSC 205
Java Programming II
2/8/2016
Modify the DeckTest program to invoke shuffle(10) (instead of simply
shuffle()). Compile and run the program again to see what happens to the
originally well ordered deck.
Attach system output for each step as described above.
1.2 Sample code: HandTest.java. This program generates and then shuffles a deck
of cards. The cards are then dealt to four players in a bridge game each has a Hand
of cards. The Hand class, which contains up to 13 cards, belongs to the
card.bridge package. This class provides a sort method that will be
implemented below.
a. Compile and run the HandTest.java program to see the dummy sort
method cannot change the order of cards in a Hand object.
b. Add the following statement to the sort method and execute again.
Collections.sort(cards);
The effect is that each hand of cards is sorted into the ascending order. In bridge,
two cards in the same suit can be compared by rank, with 2 and ace as the lowest
and highest, respectively. Suits are ranked from lowest to highest as: clubs,
diamonds, hearts, and spades. The logic is implemented in the compareTo
method in the Card class, which implements the Comparable interface.
c. In bridge literature, hands are usually sorted in the descending order: that is
spades will be listed first, and then hearts, diamonds, and clubs; in each suit, cards
are listed from ace to 2. Another sort method of the Collections class that
needs a Comparator object as parameter can sort cards in the order as defined
in the Comparator object. Belonging to the java.util package,
Comparable is an interface that requires a compare method. Read Java
online APIs at java.sun.com/javase/6/docs/api/ to compare the two interfaces.
Replace the statement you used for part b with the following code segment to see
what happens to the sorted hands.
Attach system output for each step as described above.
1.3 Follow suit. Read the method with the following header to see what the method
intends to do.
public Card pickCard(int suit)
Pay special attention to see how the iterator object is used. (Iterator is an
interface in the java.util package.)
Part 2 – Providing A BridgeHand Class Using TreeSet and TreeMap
The Hand class as described above provides a number of operations that a card game
program can use to manipulate Card objects. But it is not easy to retrieve cards by suit
and keep cards in always sorted by suit and then by rank, which is critical in a card game
such as bridge. Now let’s provide a BridgeHand class to address these issues. This new
class will use a TreeMap to manage suits: each Map.Entry contains a suit name (key)
and the corresponding collection of cards (value). The value collection is organized with
a TreeSet since there are no duplicate cards and the cards are ordered.
Lab 13-2
CSC 205
Java Programming II
2/8/2016
2.1 First, let’s write a new BridgeHand class (in the card package) and declare the
cards collection. How to take the advantage of Java generics? It makes the
declaration more complicated but much safer and easier to implement. It should read
private TreeMap<Integer, TreeSet<Card>> cards;
A no-args version constructor that instantiates a blank TreeMap will also be needed.
The following variable from the Card class is also helpful and can be added.
private static final String suits = "CDHS";
2.2 Let’s then implement the insertCard method and the toString method so that
we can do some simple testing. The insertCard method will need to check if the
suit is already in the map: if it is not there, instantiate a TreeSet suit, add the
card in suit, and then add suit into the TreeMap; otherwise, retrieve the existing
TreeSet as suit, add the card into the suit, and then add suit back into the
TreeMap. The toString method needs to generate a String representation of
the hand of card in the following format:
C:
D:
H:
S:
2 4 9 J A
5 9 J Q A
T J Q
2.3 Now let’s implement the randomPick method that removes a card at random. This
takes two steps: pick a suit that (still) exists and pick a card from it. Pick a suit can be
achieved by randomly pick a suit label from the constant suits, and check to make
sure it is in the map. With the suit label, you can retrieve the value as a TreeSet.
We can use another loop to randomly pick a rank that exists in the set. Or for
simplicity, you may remove the lowest ranking card by using
thisSuit.remove(thisSuit.first());
2.4 Next, let’s implement the pickCard(int suit) method that removes a card in a
given suit. If there is no card (left) in the given suit (i.e., size of suit is zero), the
randomPick method can be invoked to return any (remaining) card. Again, you can
remove the lowest card in the given suit.
2.5 Lastly, let’s write a BridgeHandTest class (in the card package) similar to
HandTest to test it out.
Deliverables
Your BridgeHandTest and BridgeHandTest classes and test scripts. Due by the
beginning of our final session on Friday, Dec 14.
Lab 13-3
Download