Goals for Today

23
Goals for Today implement a Deck of Cards composition Iterator interface Iterable interface 1

description

Goals for Today. implement a Deck of Cards composition Iterator interface Iterable interface. Implementing a Deck of Cards. a class to represent a deck of cards a deck has-a collection of 52 cards the deck should own the cards a deck is a composition of cards - PowerPoint PPT Presentation

Transcript of Goals for Today

Page 1: Goals for Today

Goals for Today implement a Deck of Cards

composition Iterator interface Iterable interface

1

Page 2: Goals for Today

Implementing a Deck of Cards a class to represent a deck of cards

a deck has-a collection of 52 cards the deck should own the cards

a deck is a composition of cards a client can ask the deck to deal a card

the deck gives up ownership of the card the client takes ownership of the card

a client can try to give a dealt card back to the deck the deck takes ownership of the card if and only if

it does not have the same card already class invariant: the cards in a deck are unique

2

Page 3: Goals for Today

a client can ask for the deck to be shuffled a client can ask to see all of the cards without

the deck giving up ownership of any of the cards we will implement the Iterable interface for the

deck lets clients write code like:

Deck theDeck = new Deck();

for(Card c : theDeck) // for each Card c in theDeck

{ System.out.println(c); }

3

Deck List<Card>

1

filled diamondindicates composition

Page 4: Goals for Today

Iterators an iterator is an object that provides access

to each element of a collection in sequential order

an iterator must implement the Iterator interface found in java.util

public interface Iterator<E>

{

public boolean hasNext();

public E next();

public void remove(); // optional

}

4

[AJ 16.3]

Page 5: Goals for Today

Iterable Interface every Collection type supplies an iterator by

implementing the Iterable interface

public interface Iterable<T>

{

public Iterator<T> iterator();

}

5

Page 6: Goals for Today

Iterating with hasNext prior to Java 1.5 you would iterate over a

Collection like so

6

import java.util.ArrayList;import java.util.Iterator;

// ...ArrayList<String> lst = new ArrayList<String>();lst.add("apple");lst.add("banana");lst.add("mango");for(Iterator<String> iter = lst.iterator(); iter.hasNext(); ){ String s = iter.next(); System.out.println(s.replace('a', 'A') + " ");}// prints Apple bAnAnA mAngo

Page 7: Goals for Today

Iterating with for-each the preferred method is to use a for-each loop

7

import java.util.ArrayList;import java.util.Iterator;

// ...ArrayList<String> lst = new ArrayList<String>();lst.add("apple");lst.add("banana");lst.add("mango");for(String s : lst) // for each String s in lst{ System.out.println(s.replace('a', 'A') + " ");}// prints Apple bAnAnA mAngo

Page 8: Goals for Today

Deckpackage playingcard;

import java.util.Collections;

import java.util.Iterator;

import java.util.List;

import java.util.ArrayList;

public class Deck implements Iterable<Card>

{

private final List<Card> cards;

8

Page 9: Goals for Today

Deck public Deck() {

this.cards = new ArrayList<Card>();

this.reset();

}

public void reset() {

this.cards.clear();

final Set<String> keys = CardUtil.RANKS.keySet();

for(String rank : keys) {

for(String suit : CardUtil.SUITS) {

cards.add(new Card(rank, suit));

}

}

}

9

The Deck owns its Cards; thusit must create and own its ownList of Cards.

Map does not supply an iterator to its keys or values, but it can return its keys as a Set.

Page 10: Goals for Today

Deck public void shuffle()

{

Collections.shuffle(this.cards);

}

public int getNumberOfCards()

{

return this.cards.size();

}

10

Page 11: Goals for Today

Deck public Card deal()

{

Card c = null;

if(this.getNumberOfCards() > 0)

{

c = this.cards.remove(0);

}

return c;

}

11

When a Deck deals a Card, it is giving up ownership of the Card; therefore,the Deck needs to remove the Card from its internal state. In this case, wealways deal from the top of the Deck, so we remove the first Card stored inthe List this.cards (the zeroth card).

Page 12: Goals for Today

Deck public boolean take(Card c)

{

boolean ok = false;

if (!this.cards.contains(c))

{

ok = this.cards.add(c);

}

return ok;

}

12

A client can ask a Deck to take a Card from the client; in this case, the client is asking the Deck to take ownership of the Card. Because of the class invariant (Deck holds unique Cards), the take implementation must check that the Card c is not already in this.cards. The Deck takes ownership of the Card c if and only if it does not already have a card identical to c.

Page 13: Goals for Today

Implementing equals for Deck you might be tempted to write something like

the following in equals()

eq = this.cards.equals(other.cards);

unfortunately, this does not work because the order of the list elements matters for List.equals() a list with elements { 1, 2, 3, 4 } is not equals to a

list with elements { 4, 3, 2, 1 }

13

Page 14: Goals for Today

we can use List.containsAll() a list with elements { 1, 2, 3, 4 } contains all of

the elements in the list { 4, 3, 2, 1 } but a list with elements { 1, 2, 3, 4 } also contains

all of the elements in the list { 4, 3 }

we will say that two Decks are equal if they have the same number of cards and they contain the same cards

14

Page 15: Goals for Today

Deck equals @Override public boolean equals(Object obj) {

boolean eq = false;

if (this == obj) {

eq = true;

}

else if( obj != null && this.getClass() == obj.getClass() )

{

Deck other = (Deck) obj;

eq = this.cards.size() == other.cards.size() &&

this.cards.containsAll(other.cards);

}

return eq;

}

15

Page 16: Goals for Today

Deck iterator @Override public Iterator<Card> iterator()

{

return this.cards.iterator();

}

16

Because Deck implements Iterable<Card>, we must provide a method thatreturns an iterator to a Card. We could implement our own Card iteratorclass, but the List contained by the Deck already supplies an iterator for us. In this case, we can just delegate to this.cards to get a suitable iterator.

Page 17: Goals for Today

Exercises add a constructor that constructs a Deck

given a Collection of Cards public Deck(Collection<Card> cards)

hint: use the Collections utility

add a method that sorts the Deck by rank public void sort()

hint: use the Collections utility

implement toString()

17

Page 18: Goals for Today

PEx02 Default constructor/** * Constructs a person of age 0 whose name is either * John Doe or Jane Doe. The name is randomly chosen. */public Person(){ Random gen = new Random(); if (gen.nextBoolean()) { this.name = "John Doe"; } else { this.name = "Jane Doe"; } this.age = 0;}

18

Page 19: Goals for Today

PEx02 Two-parameter Constructor/** * Constructs a person with the given name and age. * * @param name The name of the person. * @pre. <code>age >= 0</code> * @param age The age of the person. */public Person(String name, int age){ if (age < 0) { throw new IllegalArgumentException("age must be greater than or equal to zero"); } this.name = name; this.age = age;}

19

Remember that as the implementer, you can do whatever you want if the precondition is violated:age = 0;instead of the exception would also be acceptable.

Page 20: Goals for Today

PEx02 equals/**

* Tests for equality of this person and the given

* other person. Two persons are equal if they have

* the same name and the same age. If both names are

* null, then they are considered the same.

*

* @param Another person.

* @return true if this person and the other person are

* the same, false otherwise.

*/

@Override public boolean equals(Object object)

{

20

Page 21: Goals for Today

boolean eq = false;

if (this == object)

{

eq = true;

}

else if (object != null &&

this.getClass() == object.getClass())

{

// 1. cast object to Person then

// 2. do attribute by attribute equals keeping in mind

// that some attributes might need special

// handling because they can be null

21

Page 22: Goals for Today

Person other = (Person) object;

if (this.age == other.age)

{

if (this.name == null && other.name == null)

{

eq = true;

}

else if (this.name.equals(other.name))

{

eq = true;

}

}

return eq;

}

22

Page 23: Goals for Today

Puzzle 05What does the following print?

import java.util.*;

public class DatingGame {

public static void main(String[] args) {

Calendar cal = Calendar.getInstance();

cal.set(1999, 12, 31); // Dec 31, 1999?

System.out.println(cal.get(Calendar.YEAR) + " ");

Date d = cal.getTime();

System.out.println(d.getDay());

}

}

23

from Java Puzzlers by Joshua Bloch and Neal Gafter