Jump to content

Exception in thread "main" java.lang.NullPointerException

- - - - -

  • Please log in to reply
22 replies to this topic

#1
An Alien

An Alien

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 260 posts
I hate errors that I can't find.

Basically, I have a test class trying out different methods. I'll just post the tester class for now and see if you guys can spot an errors. If you guys can't, then I'll post the other 3 classes. The other classes are for deck, card, and suite. And the program worked and it compared the card's rank correctly, but it was like the same cards each time you run it just like a new deck of cards each time we run it. So I wanted to shuffle it before so I used the shuffle method right after initiializing the deck. And it stopped working and gave me that error.

Quote

Exception in thread "main" java.lang.NullPointerException
at RankCompare.main(RankCompare.java:11)
import java.util.*;

public class TestRankCompare{

	public static void main(String[] args){

		Deck deck1 = new Deck();

		deck1.shuffle(); 

		Card card1 = deck1.deal();

		Card card2 = deck1.deal();

		

		

		if (card1.getRank() > card2.getRank()){

			System.out.println("The Suit: " + card1.getSuit() + " has a rank of " + 

					card1.getRank() + " and is greater than the " + card2.getSuit() + "\n which has " +

							" the rank of: " +card2.getRank());

		}

		else{

			System.out.println("The Suit: " +card2.getSuit() + " has a rank of " +

					card2.getRank() + " and is greater than the " + card1.getSuit() + "\n which has " +

							"the rank of " + card1.getRank());

		}

	}

}


#2
Simonxz

Simonxz

    Learning Programmer

  • Members
  • PipPipPip
  • 42 posts
A NullPointerException is thrown when :

    * Calling the instance method of a null object.

    * Accessing or modifying the field of a null object.

    * Taking the length of null as if it were an array.

    * Accessing or modifying the slots of null as if it were an array.

    * Throwing null as if it were a Throwable value. 

I suspect it's the first case, make sure deck, card1 and card2 get initialized properly.

#3
An Alien

An Alien

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 260 posts
But if I remove the one line deck1.shuffle();
It works perfectly so I think the object wouldn't be null.

#4
gregwarner

gregwarner

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 853 posts
  • Location:Arkansas
I don't see any errors in the tester. Post your code for the Deck, Card, and Suite classes and we'll see if there are any errors there.

#5
wim DC

wim DC

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,084 posts
  • Programming Language:Java, JavaScript, PL/SQL
  • Learning:Java
Yup, nothing wrong there. 90% chance your deal() method returns null.

#6
An Alien

An Alien

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 260 posts
Card Class:
import java.util.*;

public class Card implements Comparable{

	

	private Suit suit;

	private int rank;

	private boolean faceUp;


	public Card(Suit suit, int rank) {

		this.suit = suit;

		this.rank = rank;

		faceUp = false;

}


public boolean equals(Object other) {

	if (this == other)

		return true;

	else if (! (other instanceof Card))

		return false;

	else{

		Card otherCard = (Card)other;

		return rank == otherCard.rank;

	}

}


public int compareTo(Object other){

	if(! (other instanceof Card))

		throw new IllegalArgumentException("Parameter must be a Card");

	Card otherCard = (Card)other;

	return rank - otherCard.rank;

}

public int getRank(){

	return rank;

}

public Suit getSuit(){

	return suit;

}

public boolean isFaceUp(){

	return faceUp;

}

public boolean isRed(){

	return suit == Suit.heart || suit == Suit.diamonds;

}

public void turn(){

	faceUp = ! faceUp;

}

public String toString(){

	return rankToString() + " of " + suit;

}


private String rankToString(){

	if (rank == 1)

		return "Ace";

	else if (rank == 11)

		return "Jack";

	else if (rank == 12)

		return "Queen";

	else if (rank ==13)

		return "King";

	else

		return "" + rank;

	}

}


Deck Class:
import java.util.*;


public class Deck{


	public static final int MAX_SIZE = 52;


	private ArrayList<Card> cards;


	public Deck(){

		reset();

}


	public void reset(){


		cards = new ArrayList<Card>();

		addSuit(Suit.spade);

		addSuit(Suit.heart);

		addSuit(Suit.diamond);

		addSuit(Suit.club);

}


	private void addSuit(Suit suit){

		for (int i = 1; i <= 13; i++)

			cards.add(new Card(suit, i));

}


	public boolean isEmpty(){

		return cards.isEmpty();

}

	public int size(){

		return cards.size();

}

	public Card deal(){

		if (isEmpty())

			return null;

		else

			return cards.remove(cards.size() - 1);

}

	public Card[] deal(int number){

		if (number > cards.size())

			return null;

		else{

			Card[] hand = new Card[number];

			for (int i = 0; i < hand.length; i++)

				hand[i] = deal();

			return hand;

	}

}



public void shuffle(){

	if (cards.size() < MAX_SIZE)

		return;

	Random gen = new Random();


	Card[] array = new Card[MAX_SIZE];

	while (cards.size() > 0){

		Card card = cards.remove(cards.size() - 1);

		int i = gen.nextInt(MAX_SIZE);

	array[i] = card;

	}

	for(Card card : array)

		cards.add(card);


}


public String toString(){

	String result = "";

	for (Card card : cards)

		result += card + "\n";

	return result;

	}

}


Suit Class:

public class Suit implements Comparable{

	

	static public final Suit spade = new Suit(4, "spades");

	static public final Suit heart = new Suit(3, "hearts");

	static public final Suit diamonds = new Suit(2, "diamonds");

	static public final Suit club = new Suit(1, "clubs");

	

	private int order;

	private String name;

	

	private Suit(int ord, String nm){

		name = nm;

		order = ord;

	}

	

	public int compareTo(Object other){

		if (!(other instanceof Suit))

			throw new IllegalArgumentException("Parameter must be a Suit");

		Suit otherSuit = (Suit)other;

		return order - otherSuit.order;

	}

	

	public String toString(){

		return name;

}

}


#7
lethalwire

lethalwire

    while(false){ ... }

  • Members
  • PipPipPipPipPipPipPip
  • 748 posts
  • Programming Language:Java, PHP
  • Learning:Java, PHP
I believe the problem lays in your shuffle method.
After shuffling the array, you should notice your ArrayList cards contains null values.
In other words, you're losing cards somewhere.

I'm thinking your random generator is the culprit. What if the generator generates a repeating number?

#8
An Alien

An Alien

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 260 posts
Well, I imported everything from java.util. What else could be the problem with the generator?

#9
lethalwire

lethalwire

    while(false){ ... }

  • Members
  • PipPipPipPipPipPipPip
  • 748 posts
  • Programming Language:Java, PHP
  • Learning:Java, PHP

lethalwire said:

I'm thinking your random generator is the culprit. What if the generator generates a repeating number?

123

#10
An Alien

An Alien

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 260 posts
I have no idea how the random generator works so IDK how I'm supposed to fix it.

#11
gregwarner

gregwarner

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 853 posts
  • Location:Arkansas

An Alien said:

Well, I imported everything from java.util. What else could be the problem with the generator?

Your shuffle method essentially does this: It deals a card off the top of the deck, then picks a random spot to put it. The problem is, you don't check for collisions. Suppose you run shuffle() and the first card comes off the deck, and the random number generator picks 37, so the card goes in position 37. Then, it picks the next card, and the random number generator gives you another random number, and on down the line. However, the random number generator is likely to have the same number come up twice. So, if some card down the line gets assigned the position 37 by the random number generator, it overwrites the first card that we stuck in that slot. Now, the overwritten card is lost forever. Additionally, there's no guarantee that every number from 1 to 52 will be picked by the random number generator, hence why some of the slots will be left empty, or null. Those nulls are what's causing your program to crash.

A better method would be to implement a list object, and then insert the cards one by one into a random spot in the list by finding the length of the list on each insert and generating a random number from zero to that length. Then, insert the card at that position, which allows the list to grow as each card is inserted. That way, you lose no cards and the deck will be complete with no null entries.

Of course, I've never implemented a card shuffling routine, so if somebody knows a better algorithm that yields a more random arrangement of cards, please chime in.
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.

– Douglas Hofstadter, Gödel, Escher, Bach: An Eternal Golden Braid


#12
An Alien

An Alien

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 260 posts
Hmm, I understand that now. Thanks Greg and Lethal.

Actually, this class wasn't written by me and was given to us in our computer science class from a text book and we're supposed to start creating the card game called "war" tomorrow. I don't exactly know how array lists work so I'll have to read up on that first cause my CS teacher doesn't know how to teach this stuff (you should read my blog posts, its funneh :D)




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users