14.2 CardCollection

下面是 CardCollection 类的初始定义,它用的是 ArrayList 而不是基本数组类型:

  1. public class CardCollection {
  2. private String label;
  3. private ArrayList<Card> cards;
  4. public CardCollection(String label) {
  5. this.label = label;
  6. this.cards = new ArrayList<Card>();
  7. }
  8. }

声明 ArrayList 时,需要在尖括号(<>)中指定它将包含的对象的类型。上述声明指出 cards 是一个包含 Card 对象的 ArrayList

构造函数接受一个字符串实参,并将其赋给实例变量 label;它还将 cards 初始化为一个空的 ArrayList

ArrayList 提供了方法 add,用于在集合中添加元素。我们给 CardCollection 添加一个执行这种任务的方法:

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

在本书前面,为方便识别属性,我们显式地使用了 this。在 addCard 和其他实例方法中,不使用关键字 this 也可访问实例变量,因此从现在开始,我们将省略 this

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

我们还需要提供将扑克牌从集合中删除的功能。下面的方法接受一个索引,删除指定位置的扑克牌,并将后面的扑克牌前移,以填补留下的空缺:

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

从一副洗好的牌中发牌时,发哪张牌无所谓,但效率最高的做法是先发最后的牌,这样就不用移动余下的牌了。下面是被重载的方法 popCard 的版本之一,它删除并返回最后一张牌:

  1. public Card popCard() {
  2. int i = size() - 1;
  3. return popCard(i);
  4. }

注意,popCard 调用了 CardCollection 的方法 size,这个方法转而调用了 ArrayList 的方法 size

  1. public int size() {
  2. return cards.size();
  3. }

出于方便考虑,CardCollection 还提供了方法 empty,它在 size0 时返回 true

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

addCardpopCardsize 这样只是调用另一个方法,而本身所做不多的方法被称为包装器方法(wrapper method)。我们将用这些包装器方法来实现一些更重要的方法,如 deal

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

方法 deal 将扑克牌从当前集合(this)中删除,并将其加入到通过参数(that)指定的集合中。第二个形参 n 指定要发多少张牌。

访问 ArrayList 的元素时,不能使用数组运算符 [],而必须使用方法 getset。下面是一个调用 get 的包装器方法:

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

方法 last 获取最后一张牌,但不删除:

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

为对修改扑克牌集合的方式进行控制,我们没有提供调用 set 的包装器方法。在我们提供的方法中,只有两个版本的 popCard 以及下述版本的 swapCards 是非纯方法:

  1. public void swapCards(int i, int j) {
  2. Card temp = cards.get(i);
  3. cards.set(i, cards.get(j));
  4. cards.set(j, temp);
  5. }

我们用 swapCards 实现 shuffle,这在 13.2 节中讨论过:

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

ArrayList 还提供了这里没有使用的其他方法。要了解这些方法,可查阅相关的文档;而要查找这些文档,可在网上搜索 Java ArrayList。