为什么我的ArrayList抛出IndexOutOfBoundsException异常?

时间:2015-06-12 03:41:06

标签: java arraylist

我正在编写这种方法来创建一个洗牌的卡片:

public static ArrayList<String> shuffle() {
    String cards[] = {"Two of Spades","Three of Spades","Four of Spades","Five of Spades", "Six of Spades","Seven of Spades", "Eight of Spades", "Nine of Spades", "Ten of Spades", "Jack of Spades", "Queen of Spades", "King of Spades", "Ace of Spades", 
                      "Two of Hearts","Three of Hearts","Four of Hearts","Five of Hearts", "Six of Hearts","Seven of Hearts", "Eight of Hearts", "Nine of Hearts", "Ten of Hearts", "Jack of Hearts", "Queen of Hearts", "King of Hearts", "Ace of Hearts",
                      "Two of Clubs","Three of Clubs","Four of Clubs","Five of Clubs", "Six of Clubs","Seven of Clubs", "Eight of Clubs", "Nine of Clubs", "Ten of Clubs", "Jack of Clubs", "Queen of Clubs", "King of Clubs", "Ace of Clubs", 
                      "Two of Diamonds","Three of Diamonds","Four of Diamonds","Five of Diamonds", "Six of Diamonds","Seven of Diamonds", "Eight of Diamonds", "Nine of Diamonds", "Ten of Diamonds", "Jack of Diamonds", "Queen of Diamonds", "King of Diamonds", "Ace of Diamonds" };
    ArrayList<Integer> numbers = new ArrayList<Integer>();
    for (int i = 0; i < 52; i++) {
        numbers.add(i);
    }
    ArrayList<String> deck = new ArrayList<String>();
    for (int i = 0; i < 52; i++) {
        Random randomizer = new Random();
        int index = randomizer.nextInt(numbers.size());
        int number = numbers.get(index);
        deck.add(numbers.get(number), cards[i]);
        numbers.remove(index);
    }
    return deck;
}

我的问题是在deck.add上,我得到一个IndexOutOfBoundsException异常。我认为ArrayList会调整大小以适应。为什么会发生这种情况,我该如何解决?这是例外:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 23, Size: 0
    at java.util.ArrayList.rangeCheckForAdd(ArrayList.java:661)
    at java.util.ArrayList.add(ArrayList.java:473)
    at game.mainGame.shuffle(mainGame.java:182)
    at game.mainGame.main(mainGame.java:32)

4 个答案:

答案 0 :(得分:5)

异常有两种可能的原因。一个是您在这两行中对numbers列表进行双索引:

int number = numbers.get(index);
deck.add(numbers.get(number), cards[i]);

问题在于,一旦您从numbers删除了某个号码,那么剩余号码中的一个很可能大于最大的合法索引。 (事实上​​,除非您碰巧按严格降序生成索引,否则这是有保证的。)另一个原因在the answer by @default locale中给出:您无法在deck中添加任意位置;如果您尝试在大于列表当前长度的位置添加元素,则双参数add()调用将生成此异常。

我建议您只使用Collections.shuffle(List)随机化numbers列表(或者更好的是,套牌本身),而不是实施自己的随机播放。

这是我shuffle()的版本:

private static final List<String> cards = Arrays.asList(
    "Two of Spades","Three of Spades","Four of Spades","Five of Spades", "Six of Spades","Seven of Spades", "Eight of Spades", "Nine of Spades", "Ten of Spades", "Jack of Spades", "Queen of Spades", "King of Spades", "Ace of Spades", 
    "Two of Hearts","Three of Hearts","Four of Hearts","Five of Hearts", "Six of Hearts","Seven of Hearts", "Eight of Hearts", "Nine of Hearts", "Ten of Hearts", "Jack of Hearts", "Queen of Hearts", "King of Hearts", "Ace of Hearts",
    "Two of Clubs","Three of Clubs","Four of Clubs","Five of Clubs", "Six of Clubs","Seven of Clubs", "Eight of Clubs", "Nine of Clubs", "Ten of Clubs", "Jack of Clubs", "Queen of Clubs", "King of Clubs", "Ace of Clubs", 
    "Two of Diamonds","Three of Diamonds","Four of Diamonds","Five of Diamonds", "Six of Diamonds","Seven of Diamonds", "Eight of Diamonds", "Nine of Diamonds", "Ten of Diamonds", "Jack of Diamonds", "Queen of Diamonds", "King of Diamonds", "Ace of Diamonds"
);

public static ArrayList<String> shuffle() {
    final ArrayList<String> deck = new ArrayList<String>(cards);
    Collections.shuffle(deck);
    return deck;
}

答案 1 :(得分:2)

方法ArrayList.add(int index, E element)This input has no placeholder on Desktops&nbsp;<input name="name" type="text" placeholder="insert your name">放在指定的位置element上。 方法抛出index - 如果索引超出范围(索引&lt; 0 || index&gt; size())

IndexOutOfBoundsException

由于你的arraylist deck.add(numbers.get(number), cards[i]); 在开头是空的(size()= 0),你只能在索引0上添加元素,因为任何其他索引都会抛出异常。

您可能希望生成随机卡而不是随机位置。查看以前的答案,了解改组的其他建议。

答案 2 :(得分:1)

问题在于deck.add(indexA,objectB)方法,因为你试图在indexA中放置一张卡片,它可能不存在。即indexA的值必须介于0和deck.size()之间。您需要更改代码逻辑。

java doc链接供参考:

http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html

答案 3 :(得分:0)

像这样改变循环:

    for (int i = 0; i < 52; i++) {
        Random randomizer = new Random();
        int index = randomizer.nextInt(numbers.size());
        int number = numbers.get(index);
        deck.add(cards[number]);
        numbers.remove(index);
    }