0

看看以下用于构建卡片组的代码。我正在使用 xFactor“变量”(硬编码)从数组大小中减去 1 以调整零索引。我注意到,在遇到“java.lang.ArrayIndexOutOfBoundsException: 12”错误之前,我实际上总共可以减去 40。

如果我输入 39 作为 xFactor,它运行得非常好。它构建了整个牌组,所有 52 张牌,尽管奇怪的是,cards.length 将等于每个循环两侧的 deckTotal - xFactor?!?这没有意义,因为它需要达到 51 的索引才能构建整个甲板,它确实......

public void constructDeck(){
    int deckTotal = SUITS.length * CARDS_PER_SUIT;
    System.out.println(deckTotal); // 52
    Card[] cards = new Card[deckTotal - xFactor]; 
    System.out.println(cards.length); // Prints deckTotal - xFactor
    for(String cardSuit : SUITS){
        int cardNum = 1;
        while(cardNum <= CARDS_PER_SUIT){
            String cardDesc = cardDescription(cardNum);
            int cardValue = cardNum;
            if(cardNum >= VALUE_CEILING){
                cardValue = VALUE_CEILING;
            }
            cards[cardNum -1] = new Card(cardDesc,cardSuit,cardValue);

            this.deck.addCard(cards[cardNum -1]);
            //System.out.println(cardDesc + " of " + cardSuit + " added to the deck");
            cardNum++;
        }
    }
    System.out.println(cards.length);  // prints: deckTotal - xFactor
}

我唯一能想到的是,内存正在从阵列的开始被修剪,以便腾出空间新卡被添加到后面。所以这意味着 ArrayIndexOutOfBoundsException 实际上只是我的计算机处理循环和/或收集垃圾的速度的函数。

我编写这段代码只是为了测试 Java 类介绍的一个非常基本的任务。来自 JS 背景,在使用之前声明数组的大小似乎有点奇怪(尽管我明白为什么)。不过,这里的行为确实出乎意料,我很好奇幕后发生了什么。

更新: 谢谢你的建议。这是我根据您的建议编写的最终代码。

public void constructDeck(){
    for(String cardSuit : SUITS){
        int cardNum = 1;
        while(cardNum <= CARDS_PER_SUIT){
            String cardDesc = cardDescription(cardNum);
            int cardValue = cardNum;
            if(cardNum >= VALUE_CEILING){
                cardValue = VALUE_CEILING;
            }
            this.deck.addCard(new Card(cardDesc,cardSuit,cardValue));
            cardNum++;
        }
    }
}
4

2 回答 2

3

您使用 . 访问卡片数组。cards[cardNum -1]这意味着您只使用数组中的前 12 个元素。(不同的西装是写在以前的西装)

因此,只要 xFactor 允许至少 12 张卡存在,代码就可以工作..(可能不是您所期望的 :))

查看代码你真的根本不需要数组

       this.deck.addCard( new Card(cardDesc,cardSuit,cardValue) );
于 2014-11-18T08:50:34.737 回答
1

您只是在包含范围 [0, CARDS_PER_SUIT-1] 中填充卡片数组查看此行:

cards[cardNum -1] = new Card(cardDesc,cardSuit,cardValue);

每个花色的变量cardNum都重置为 1,因此您只需继续覆盖相同的范围。

我认为您误解了数组的分配方式。您应该分配大小。只有索引应该停止。52 张卡片的数组应分配大小为 52,索引范围包括 [0,51],即 52 个插槽。

我认为这更接近你想要的:

public void constructDeck(){
    int deckTotal = SUITS.length * CARDS_PER_SUIT;
    System.out.println(deckTotal); // 52
    Card[] cards = new Card[deckTotal]; //Allocate all the cards. 
    System.out.println(cards.length); // Prints deckTotal
    int suitOffset=0;
    for(String cardSuit : SUITS){
        int cardNum = 1;
        while(cardNum <= CARDS_PER_SUIT){
            String cardDesc = cardDescription(cardNum);
            int cardValue = cardNum;
            if(cardNum >= VALUE_CEILING){
                cardValue = VALUE_CEILING;
            }
            cards[suitOffset*CARDS_PER_SUIT+cardNum -1] = new Card(cardDesc,cardSuit,cardValue);

            this.deck.addCard(cards[cardNum -1]);
            //System.out.println(cardDesc + " of " + cardSuit + " added to the deck");
            cardNum++;
        }
        ++suitOffset;
    }
    System.out.println(cards.length);  // prints: deckTotal 
    //Now lets dump the cards to output and show we're dealing with a full deck!
    //I'm assuming Card.toString() has been overridden to return something useful like
    //the description.
    for(int i=0;i<cards.length;++i){
        System.out.println("cards["+i+"]="+cards[i].toString()); 
    }
}

但是我不确定你为什么将它们都添加到对象“this.deck”对象和本地数组中。我猜,但从这个片段中不清楚你是否需要数组cards,如果你可以访问this.deck.

于 2014-11-18T09:05:16.327 回答