java - 为什么此代码会抛出 ArrayIndexOutOfBoundsException?

标签 java arrays

代码如下:

public class Deck {

    private Card[] cards;

    public Deck() {
        cards = new Card[52];
        String[] ranks = {"ace","two","three","four","five","six","seven","eight","nine","ten","jack","queen","king"};
        String[] suits = {"hearts","diamonds","clubs","spades"};
        for(int i = 0; i < suits.length; i++) {
            for(int n = 0; n < ranks.length; n++) {
                cards[cards.length] = new Card(ranks[i],suits[n]);
            }
        }
    }
}

如您所见,这会循环遍历两个给定数组并为每个组合生成一张卡片。有 13 个等级 x 4 个花色 = 52 张牌。我预计在第 52 次迭代时,cards.length 将是 51,但编译器说

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 52
    at com.cards.Deck.<init>(Deck.java:14)

这是为什么?

最佳答案

问题是 cards.length 不是数组中使用的元素总数;它是数组中的元素总数,不管到目前为止您在数组中存储了什么。因此,一旦您执行内部循环,这将尝试访问数组的第 52 个元素,从而导致您看到的异常。

要解决此问题,请考虑改为存储一个计数器来跟踪下一个空闲索引,或者使用一些简单的数学运算从其花色和值(value)中推导出牌应该进入的位置。例如,由于在外循环的每次迭代中,您都会将 ranks.length 元素写入数组,因此在迭代 (i, n)您将写入数组索引 i * ranks.length + n。使用它,您可以将内部循环重写为

    // Careful... still buggy!
    for(int i = 0; i < suits.length; i++) {
        for(int n = 0; n < ranks.length; n++) {
            cards[i * ranks.length + n] = new Card(ranks[i],suits[n]);
        }
    }

此外,请注意您对数组的访问是错误的。现在,你正在写

new Card(ranks[i],suits[n]);

但是,i 范围超过花色,而不是值。正确的代码是

new Card(ranks[n],suits[i]);

这给出了最终的实现:

    for(int i = 0; i < suits.length; i++) {
        for(int n = 0; n < ranks.length; n++) {
            cards[i * ranks.length + n] = new Card(ranks[n],suits[i]);
        }
    }

不过,更一般地说,不要使用数组的 .length 字段来跟踪有多少已使用的元素。您需要单独存储它。或者,考虑使用 ArrayList,它包装一个数组并为您跟踪它。

希望这对您有所帮助!

关于java - 为什么此代码会抛出 ArrayIndexOutOfBoundsException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7424413/

相关文章:

java - 为什么这个缓冲的阅读器没有收到任何数据?

java - 为什么 Eclipse 在 Override 上给我这个注释错误

sql - PostgreSQL 可以在 jsonb 数组对象上加入吗?

java - Java Arrays.hashcode() 的 hashcode 实现是否均匀分布

java - java中的numberformatexception

java - 如何解决这个并发问题呢?

java - 术语:数组的第 X 个元素与索引 X 处的元素

javascript - 使用带有 Fetch API 响应的 promise 仍然会使我的数据返回为未定义

java - for循环遍历不同的数组/Java

ios - 如何在 NSMutableArray 中添加不同的不同键值?