Skip to main content
Engineering LibreTexts

5.2: CardCollection

  • Page ID
    15299
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    Here’s the beginning of a CardCollection class that uses ArrayList instead of a primitive array:

    public class CardCollection {
    
        private String label;
        private ArrayList<Card> cards;
    
        public CardCollection(String label) {
            this.label = label;
            this.cards = new ArrayList<Card>();
        }
    }
    

    When you declare an ArrayList, you specify the type it contains in angle brackets (<>). This declaration says that cards is not just an ArrayList, it’s an ArrayList of Card objects.

    The constructor takes a string as an argument and assigns it to an instance variable, label. It also initializes cards with an empty ArrayList.

    ArrayList provides a method, add, that adds an element to the collection. We will write a CardCollection method that does the same thing:

    public void addCard(Card card) {
        this.cards.add(card);
    }
    

    Until now, we have used this explicitly to make it easy to identify attributes. Inside addCard and other instance methods, you can access instance variables without using the keyword this. So from here on, we will drop it:

    public void addCard(Card card) {
        cards.add(card);
    }
    

    We also need to be able to remove cards from a collection. The following method takes an index, removes the card at that location, and shifts the following cards left to fill the gap:

    public Card popCard(int i) {
        return cards.remove(i);
    }
    

    If we are dealing cards from a shuffled deck, we don’t care which card gets removed. It is most efficient to choose the last one, so we don’t have to shift any following cards. Here is an overloaded version of popCard that removes and returns the last card:

    public Card popCard() {
        int i = size() - 1;
        return popCard(i);
    }
    

    Notice that popCard uses CardCollection’s own size method, which in turn calls the ArrayList’s size method:

    public int size() {
        return cards.size();
    } 

    For convenience, CardCollection also provides an empty method that returns true when size is zero:

    public boolean empty() {
        return cards.size() == 0;
    } 

    Methods like addCard, popCard, and size, which invoke another method without doing much additional work, are called wrapper methods. We will use these wrapper methods to implement less trivial methods, like deal:

    public void deal(CardCollection that, int n) {
        for (int i = 0; i < n; i++) {
            Card card = popCard();
            that.addCard(card);
        }
    } 

    The deal method removes cards from the collection it is invoked on, this, and adds them to the collection it gets as a parameter, that. The second parameter, n, is the number of cards to deal.

    To access the elements of an ArrayList, you can’t use the array [] operator. Instead, you have to use the methods get and set. Here is a wrapper for get:

    public Card getCard(int i) {
        return cards.get(i);
    }
    

    The last method gets the last card (but doesn’t remove it):

    public Card last() {
        int i = size() - 1;
        return cards.get(i);
    } 

    In order to control the ways card collections are modified, we don’t provide a wrapper for set. The only modifiers we provide are the two versions of popCard and the following version of swapCards:

    public void swapCards(int i, int j) {
        Card temp = cards.get(i);
        cards.set(i, cards.get(j));
        cards.set(j, temp);
    } 

    We use swapCards to implement shuffle, which we described in Section 13.2:

    public void shuffle() {
        Random random = new Random();
        for (int i = size() - 1; i > 0; i--) {
            int j = random.nextInt(i);
            swapCards(i, j);
        }
    } 

    ArrayList provides additional methods we aren’t using here. You can read about them in the documentation, which you can find by doing a web search for “Java ArrayList”.


    This page titled 5.2: CardCollection is shared under a CC BY-NC-SA 3.0 license and was authored, remixed, and/or curated by Allen B. Downey (Green Tea Press) .

    • Was this article helpful?