12.6 Card数组

可创建 String 对象数组,同样,也可创建 Card 对象数组。下面的语句创建了一个数组,其中包含 52 个 Card 对象:

  1. Card[] cards = new Card[52];

图 12-2 是这个数组的状态图。

图像说明文字

图 12-2:一个未填充的 Card 数组的状态图

虽然我们称之为“Card 对象数组”,但这个数组包含的是指向 Card 对象的引用,而不是 Card 对象本身。这个数组的元素被初始化为 null,可像通常那样访问:

  1. if (cards[0] == null) {
  2. System.out.println("No card yet!");
  3. }

然而,如果试图访问不存在的 Card 对象的实例变量,那么将引发 NullPointerException 异常。

  1. cards[0].rank // NullPointerException

Card 对象填充这个数组前,上述代码不可运行。编写嵌套 for 循环是填充数组的一种办法:

  1. int index = 0;
  2. for (int suit = 0; suit <= 3; suit++) {
  3. for (int rank = 1; rank <= 13; rank++) {
  4. cards[index] = new Card(rank, suit);
  5. index++;
  6. }
  7. }

外面的循环迭代花色(从 0~3)。对于每种花色,内部的循环迭代点数(从 1~13)。由于外面的循环运行 4 次,里面的循环运行 13 次,因此循环体被执行 52 次。

我们使用了一个独立变量来跟踪下一张牌应存储在数组的什么地方,图 12-3 显示了创建开头两张牌后这个数组是什么样的。

图像说明文字

图 12-3:一个包含两张牌的 Card 数组的状态图

处理数组时,如果有一个显示其内容的方法将很方便。你已经见过很多次数组遍历模式,因此对下面的方法应该不会感到陌生:

  1. public static void printDeck(Card[] cards) {
  2. for (int i = 0; i < cards.length; i++) {
  3. System.out.println(cards[i]);
  4. }
  5. }

由于变量 cards 的类型为 Card[],因此其元素的类型为 Card,所以 println 将调用 Card 类的方法 toString。上述方法的效果与调用 System.out.println(Arrays.toString(cards)) 类似。