Here’s the code:
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]);
}
}
}
}
As you can see, this loops though the two given arrays and generates a card for every combination. There are 13 ranks x 4 suits = 52 cards. I expected that on the 52nd iteration, cards.length would be 51, but the compiler says
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 52
at com.cards.Deck.<init>(Deck.java:14)
Why is that?
The issue is that
cards.lengthis not the total number of elements used in the array; it’s the total number of elements in the array, regardless of what you’ve stored in the array so far. Consequently, as soon as you execute the inner loop, this will try accessing the 52nd element of the array, causing the exception you’ve seen.To fix this, consider instead storing a counter that will keep track of the next free index, or use some simple math to derive the position that the card should go in from its suit and value. For example, since on each iteration of the outer loop you will write
ranks.lengthelements to the array, on iteration (i,n) you will write to array indexi * ranks.length + n. Using this, you could rewrite the inner loop asAdditionally, note that your access into the arrays is wrong. Right now, you’re writing
However,
iranges over suits, not values. The proper code would beWhich gives this final implementation:
More generally, though, don’t use the
.lengthfield of an array to track how many used elements there are. You’ll need to store that separately. Alternatively, consider using anArrayList, which wraps an array and tracks this for you.Hope this helps!