Why is my ArrayList throwing an IndexOutOfBoundsException?

I am writing this method to create a shuffled deck of cards:

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;
}

      

My problem here is that on deck.add I get an IndexOutOfBoundsException. I thought the ArrayList would resize. Why is this happening and how can I fix it? Here's the exception:

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)

      

+3


source to share


4 answers


There are two possible reasons for exclusion. First, you are indexing into the list twice numbers

on these two lines:

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

      

The problem is that after removing a number from numbers

, there is a good chance that one of the remaining numbers is larger than the largest legal index. (Actually, this is guaranteed, unless you generate indexes in strictly descending order.) Another reason is given in the answer to @default locale : you cannot add to arbitrary positions in deck

; a two-argument call add()

will throw this exception if you try to add an item at a position greater than the current length of the list.



Instead of using your own shuffle, I suggest you just use Collections.shuffle(List)

to randomize the list numbers

(or better, the deck itself).

Here's my version 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;
}

      

+5


source


The ArrayList.add (int index, element E) method places element

at the specified position index

. Throws method IndexOutOfBoundsException

- if index is out of range (index <0 || index> size ())

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

      



Since your arraylist is deck

empty (size () = 0), at the beginning you can only add items at index 0, for any other exception the index will be thrown.

You might want to create random cards rather than random positions. Check previous answers for alternative shuffle suggestions.

+2


source


Edit for loop like this:

    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);
    }

      

0


source


The problem is with the deck.add (indexA, objectB) method, because you are trying to put a card in the deck at indexA, which may be missing. ie indexA must be between 0 and deck.size (). You need to change your code logic.

java doc link for reference:

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

0


source







All Articles