Question

I am having an error with my BlackJack Java game. The error is:

Exception in thread "main" java.lang.NullPointerException
at com.keegan.game.blackjack.Deck.createDeck(Deck.java:48)
at com.keegan.game.blackjack.Deck.<init>(Deck.java:33)

And I am pretty clueless as to what the problem is in this code. Can anyone help me understand what the error is telling me that is wrong?

Here is the code for Deck.java:

public class Deck {

private ArrayList<Card> deck = new ArrayList<Card>();

private List<Card> cardUsed = new ArrayList<Card>();
Card c = new Card(null, null, null, 0);

public Deck(int numCards) {
    this.createDeck(numCards, 4, null);
}

private void createDeck(int numCards, int numSuits, String[] cardRanks) {
    deck = new ArrayList<Card>();
    cardUsed = new ArrayList<Card>();
    if ((numCards % numSuits) > 0) return;
    for (int i=0; i < numSuits; i++) {
        for(int j=1; j <= (numCards / numSuits); j++) {
            deck.add(new Card(new Suit(i), cardRanks[j-1], cardRanks, j));
        }
    }
}

public Card dealCard( ) {

    Card dealtCard = null;
    if (deck.size() == 0){
        deck.addAll(cardUsed);
        this.shuffle();
        cardUsed = new ArrayList<Card>();
    }

    dealtCard = deck.get(0);
    deck.remove(0);
    cardUsed.add(dealtCard);

    return dealtCard;
}

public void shuffle() {
    Collections.shuffle(deck);
}

public ArrayList<Card> getDeck() {
    return deck;
}

public void setDeck(ArrayList<Card> deck) {
    this.deck = deck;
}
public int getNumUsedCards() {
    return cardUsed.size();
}

public List<Card> getCardUsed() {
    return cardUsed;
}

public void setCardUsed(List<Card> cardUsed) {
    this.cardUsed = cardUsed;
}
Was it helpful?

Solution

You're passing a null array

this.createDeck(numCards, 4, null);

and later accessing it as cardRanks[j-1] in your statement

deck.add(new Card(new Suit(i), cardRanks[j-1], cardRanks, j));

EDIT :
What you probably need is to create your Deck as

this.createDeck(numCards, 4);

and adding the Card as

deck.add(new Card(new Suit(i), j));

since, String[] cardRanks is already initialized in your Card class. And, design-wise it's correct because Deck shouldn't have to know about card ranks. Card should encapsulate it and maybe implements Comparable as well.

OTHER TIPS

In you constructor you have passed null as a variable

public Deck(int numCards) {
    this.createDeck(numCards, 4, null);
}

within your method createDeck you then try to use that variable

private void createDeck(int numCards, int numSuits, String[] cardRanks) { //<---cardRanks is null at this point
    deck = new ArrayList<Card>();
    cardUsed = new ArrayList<Card>();
    if ((numCards % numSuits) > 0) return;
    for (int i=0; i < numSuits; i++) {
        for(int j=1; j <= (numCards / numSuits); j++) {
            deck.add(new Card(new Suit(i), cardRanks[j-1], cardRanks, j)); 
        }
    }
}

When you write cardRanks[j-1] you are trying to access the "inside" of cardRanks. If cardRanks is null, i.e. doesn't exist, then it can't access the inside and a NullPointerException is its only option. Java understandably complains.

In english what you are telling the program to do (when cardRanks is null) is to take the j-1 element of 'nothing'. This clearly is meaningless and a NullPointerException is how the compiler tells you


Creating arrays of strings that are not null

String[] stringArray=new String[10]; //creates an array big enough to hold 10 Strings

At present the stringArray holds 10 nulls

stringArray[0]="hi"; //enter first element
stringArray[1]="hi again"; //enter second element
stringArray[2]=""; //empty string is not the same as null

Now the first 3 elements are non null, the remaining 7 remain null

you could of course create your strings in a loop or in any way you see fit

Creating a class that doesn't need to take its fields in a constructor

public class SomeClass {
    String[] someStringArray={"hello", "i'm just fine as I am"}; //creates an array of strings, 2 entries

    int someNumber;

    public SomeClass(int someNumber){
        //this constructor leaves someStringArray alone, its fine as it is
        this.someNumber=someNumber;

    }

    public SomeClass(int someNumber,String[] someStringArray){
        //this constructor changes someStringArray
        this.someNumber=someNumber;
        this.someStringArray=someStringArray;

    }

}
deck.add(new Card(new Suit(i), cardRanks[j-1], cardRanks, j));

in this line the cardRanks is null. As you called the method as

this.createDeck(numCards, 4, null);

You can't access a element of null array (:p)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top