• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

NullPointerException when accessing array element

 
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


Hi everybody,

The attached codelet is from my program shuffling a deck of cards.
I declare saveCard to be a member of the Card class in line 2, but still get get a Null POInter Exception at line 8.
I feel this must be something very obvious,  but I can not work it out.
Any advice would be appreciated.
Bob
 
Saloon Keeper
Posts: 7585
176
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Has the "card" array been initialized? Does each array element contain a "Card" object? It's hard to say how to correct the code without seeing the parts where that happens.
 
Rancher
Posts: 517
15
Notepad Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Where is the card array initialized, and what is it initialized with (in the following code snippet)?

 
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I don't like arithmetic with Math#random. More information here. Use Random#nextInt instead.
Tim M and PS are right if you are getting that exception on line 8, you haven't initialised the array correctly.
Please search this forum for things about shuffling, well actually search for this thread and this post. It is not actually possible fairly to shuffle a 52‑card pack because the number of different orders (=52!) is too high for a Random object to handle. The naïve version of shuffling you have used gives a biased result; the algorithm used by Collections#shuffle is better, but it only works on a List, so you will have to change it slightly for an array.
 
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:The naïve version of shuffling you have used...


Apart from the use of Math.random() instead of Random.nextInt(int), what's naive about OP's algorithm? It's essentially the same as the Collections.shuffle() algorithm if you ignore the traversal order.

Edit: Ok, I take that back. You can't ignore the traversal order and still claim it's basically the same algorithm. Collections.shuffle algorithm will not touch cards that have already been moved, whereas OP's algorithm will. It's a subtle but important difference.
 
Junilu Lacar
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
OP, to help you visualize your algorithm, think of it this way:

Lay all your cards out on a table, say in a 4 x 13 grid pattern, like you're playing the memory game. Pick two random cards and swap them. Repeat this 52 times. Going by the same order you laid them down, swap each card with another card that you randomly select from anywhere on the grid (this means you'll do this 52 times, assuming you're using a standard deck). Gather up all the cards again, in the same order you laid them down on the table.

With this algorithm, it is possible that you will move one or more cards around multiple times. It is possible that multiple cards will end up being put back in their original location.

The way Collections.shuffle() does it is basically this: Hold the deck in your hand. Pick a random card from the deck. Set that card on the table.  Pick another random card from the deck in your hand and put it on top of the first one you picked that's on the table. Repeat until you have no cards in your hand. The deck you have on the table is now shuffled randomly.

This algorithm guarantees that all cards will have, at most, one chance of being moved.
 
Campbell Ritchie
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Junilu Lacar wrote:. . . It's a subtle but important difference.

. . . which I have overlooked in the past myself. Ignoring previously shuffled elements removes one source of bias.

Whether the problem about 2⁶⁴ being so much less less than 52! can be solved by creating a new Random object each iteration of the loop, I don't know. It means there are only 2⁶⁴ possible seeds and therefore 2⁶⁴ possible paths through a shuffle algorithm. Whether a new Random object would change that to (2⁶⁴)⁵² possible paths or 52! possible paths, as I said, don't know.
 
Ranch Hand
Posts: 65
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You created the array but didn't put anything in it, so you have an array that contains 5 elements, all of which are null. You could add

boll[0] = new ResultList();
 
Sheriff
Posts: 7125
184
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

sonai kale wrote:You created the array but didn't put anything in it, so you have an array that contains 5 elements, all of which are null. You could add

boll[0] = new ResultList();


Nothing in this post makes sense to me.  There is no array created in the code.  Nothing with five null elements.  No array named "boll."  No ResultList type.
 
Robert Manley
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


HI everyone,
Attached is the complete code. the offending line is line 69.
createDeck() generates all 0-51 indexed cards so the cards appear to be properly defined.

Bob
 
Saloon Keeper
Posts: 10705
86
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
this.card and card are one and the same, so it's like saying i = i. You don't have a local 'card' variable so it is the class member variable 'card' which is the same as 'this.card'.
 
Carey Brown
Saloon Keeper
Posts: 10705
86
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
On line 45 you create a new variable 'card' which you then proceed to fill on line 55. However, you return from the method without doing anything with your 'card' variable, so it just gets garbage collected.
 
Carey Brown
Saloon Keeper
Posts: 10705
86
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You haven't created an equals() method for your Card class so you are getting the default behavior inherited from the Object class. The default is to see if cards[i] and target refer to the exact same object. I think you're intending to find a card with the same suit and rank as the target. For that you'll have to create an equals() method that does that.
 
Knute Snortum
Sheriff
Posts: 7125
184
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
int i is never used.
 
Knute Snortum
Sheriff
Posts: 7125
184
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
int temp is never used.
 
Knute Snortum
Sheriff
Posts: 7125
184
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
cards[] needs to be sorted for this to work.

Are you sure you want to compare cards by their toString() method?  Won't this make the sort order different than the rank?
 
Robert Manley
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


Hi again everyone,

I have done all the mods everyone suggested including using Random.nextInt().
It appears to make no difference whether I comment out "this.card = card;" on line 50, or leave it in.
I have declared "private static Card[] card = new Card[52] ;" in line 46.
I have made the comparison more exhaustive on line 97 in seqSearch().
there probably should be something similar in binarySearch() .
I have created private static Card card in line 4 of main().

createDeck() and shuffle() both do what is expected, but  I get another "null pointer exception"  when seqSearch() tries to run. Similarly for binarySearch() if I reverse the order.
Bob
 
Robert Manley
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I should say I appreciate all the help you guys give.
It can't be much fun wading through some of this stuff.
Thanks again.
Bob
 
Carey Brown
Saloon Keeper
Posts: 10705
86
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Lines 8 and 46 both create a Card[] that is private, and one can't see the other. So on line 10 where you call createDeck(), that call has no effect on the "card" array on line 8 and therefore the "card" array on line 8 is entirely filled with nulls. Then on line 12, you pass in card[5] as the target, and we now know that card[5] contains null.

EDIT: I missed the one on line 4 as well. So you've created 3 arrays of cards.
 
Carey Brown
Saloon Keeper
Posts: 10705
86
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In Deck you have
Because you have no local variable "card", this is equivalent to
Which is equivalent to
 
Robert Manley
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


Hi again,

I have created 2 card arrays for orderedCard filled by createDeck(), and shuffledCard filled by shuffle().
I have determined in lines
 
Robert Manley
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
...sorry, I hit the wrong button.
The 'null pointer exception' is caused by the references to 'target' as output from lines 103 - 107 indicates, ie., it now crashes at 106.
createDeck() and shuffle() are correctly filling the arrays orderedCard() and shuffledCard().
I have placed a statement in line 47 to define the target as orderedCard[5] (2 of Clubs). This is the wrong place I know, but I have had no luck putting it in the main method.
Can you please explain to me how to refer to the 'target' correctly.
Every time i put it in 'main' I get red lettering, and if I delete line 47 in Deck I get errors there as well.

Thanks
 
Campbell Ritchie
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Why are you setting the target field up like that? Work out what you are initialising it to first.
[edit]Latest post, lines 45‑47.
 
Carey Brown
Saloon Keeper
Posts: 10705
86
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Carey Brown wrote:In Deck you have
Because you have no local variable "card", this is equivalent to
Which is equivalent to


You are still doing this in lines 50-53.
 
Knute Snortum
Sheriff
Posts: 7125
184
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Stop everything you are doing until you get what Carey Brown is saying.  Nothing will work correctly until you do.
Carey has told you three times (I believe) that this pattern doesn't work.  Are you trying to set someField through the constructor?  If so, you are missing something vital.  What is it?
 
reply
    Bookmark Topic Watch Topic
  • New Topic