• Post Reply Bookmark Topic Watch Topic
  • New Topic

Help Please  RSS feed

Kenyan Khan
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey, i have the following code, it makes a map, but i keep getting a null pointer exception in my remove method. Anyone help me??? Pls
import java.lang.Math;
class Node{
Object key;
Object data;
Node next;

public Node (Object k, Object d, Node n){
key = k;
data = d;
next = n;

}//end of constructor
}// end of node class

public class Map{
public Map (int cap){

capacity = cap;
map = new Node[capacity];

int size=0;
int arraySize=0;
int placement = 0;
}//initialiser constructor

public Map () {

capacity = 11;
map = new Node[capacity];
int placement = 0;
int size = 0;
int arraySize =0;

private static int arraySize;
private static int capacity;
private static Node map[];
private static Node head;
private static Node oldHead;
private static int size;
private static int placement;

public static Object[] keys (){
System.out.println("KEYS METHOD ENTERED"); System.out.println();
Object arrayB[] = new Object[capacity];
int counterB = 0;
for (int counter = 0; counter < capacity ; counter++){

if (map[counter] != null){//list stored here

for (Node p = map[counter]; p != null; p = p.next){

arrayB[counterB] = p.key;


}//end of for

}//end of if

}//end of for

System.out.println("KEYS METHOD EXITED"); System.out.println();
return arrayB;

}//end of method
public static void remove(Object key){

for(int counter = 0; counter< capacity; counter ++){
// controls movement along array


// 1) Node could be first in list
// 2) Further into the list
// 3) Not exist in this list, or the Map at all
// 1) If the node is first in the list:

if(map[counter].data == key){
// a) There are no following nodes after this one
// b) There is a list following on.

if(map[counter].next == null){
if(map[counter].next != null){
map[counter] = map[counter].next;
}//end of if

else{//the node is further in
Node prev = map[counter]; System.out.println("Got here fucker");
for(Node q = map[counter]; q!= null; q=q.next){
//established that not first node, so started at next one
if(q.data == key){// must remove
if(q.next ==null){// then this is the last node in the list
prev.next = null; // node is removed by garbage collector
if(q.next!=null){//this is in the middle of a list
prev.next = q.next; // node removed
prev = q; // other increments controlled by for loop

}//end of for
}//end of else

}//end of else

}//end of for loop


public static Object get (Object key) {
Object returnKey = "";//done to avoid null being printed out
for(int counter = 0; counter < capacity; counter ++){
if(map[counter] != null){ //there is a list here
for(Node scan = map[counter]; scan!= null; scan = scan.next){
if(scan.data == key){
returnKey = scan.data;
}//end of for loop for linked list

}//end of != null if
}//end of for loop

return returnKey;
}//end of get method
public static Object put (Object key, Object value){
Object toReturn = null;
/** System.out.println("PUT METHOD ENTERED"); System.out.println();
System.out.println("Current Key is "+key); */
placement = key.hashCode () % capacity;
/** System.out.println("placement " + placement);
System.out.println("Capacity " + capacity); */
if (map[placement] != null){//means we won't have to rehash as not adding to a new slot in array
System.out.println(" != null entered with key "+ key);
Node scanner = map[placement];
Node prev = scanner; //toReturn remains null, as nothing before it
for(scanner=map[placement]; scanner!=null; scanner = scanner.next){

if(scanner.next == null){//time to add
prev.next = new Node(key, value, null);
toReturn = prev.data;//this is where we added on
if(scanner.next!= null){//must keep going thorough the list, so move to scanner, done by for loop
//prev = scanner;
prev = scanner;


System.out.println(" != null if exited");
}//end of if 1
if (map[placement] == null){//then we are about to add to a new section in the array, we must make sure we do not
// exceed the load factor

if ((arraySize + 1) < (Math.floor(capacity * 0.75))){//no rehash is needed
map[placement] = new Node (key, value, null);
System.out.println(" Came to no rehash if in put method");

}//end of size 1 if

Object tempKey = key; //don't want these to change during rehash
Object tempVal = value;
Map.put (tempKey, tempVal);
System.out.println(" Came to rehash if");
}//end of if 2

}//end of if 2

return toReturn;
}//end of method
public static int size (){
return size;
public static void rehash (){
System.out.println("REHASH METHOD ENTERED"); System.out.println();
Object toBeHashed[] = Map.keys ();

size = 0; // no more objects in the array
int oldCapacity = capacity;
capacity = capacity * 2; arraySize =0;
Node temp[] = new Node[capacity];//because we cannot change the size of the old array

map =temp;
for (int j = 0; j < oldCapacity; j++)
Map.put (toBeHashed[j], toBeHashed[j]);
System.out.println("REHASH METHOD EXITED");
}// end of rehash method

}// end of class

Tester Class:
public class A4Test {
public static void main( String a[] ) {
String s[]={"ape","bat","cat","dog","fox","gnu","hog","pig"};

Map m = new Map(3); // init capacity 3
for( int i = 0; i < s.length; i++ ){
m.put( s[i], s[i] );

Object b[] = m.keys();


for( int i = 0; i < b.length; i++ )
System.out.print( ((String)m.get( b[i] )) + " ");

Stefan Wagner
Ranch Hand
Posts: 1923
Linux Postgres Database Scala
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[Please use a better] subject [than] 'Please help'.
Make specific subjects! (At least: Map problem).
Use the code-Button and indentation to make your listing readable.
Describe it in brief words.
Shrink your code down to the very minimum.
[Edited for niceness by EJFH]
[ February 21, 2004: Message edited by: Ernest Friedman-Hill ]
Ernest Friedman-Hill
author and iconoclast
Posts: 24217
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the helpful answers you've provided to other questions on JavaRanch! Do please remember, though, that the number one rule here is "Be Nice." We don't growl at JavaRanch members. It's fine to give people advice on how to post. It's not fine to make someone feel bad for posting in the first place. We have a very low tolerance for unkind behavior. Consider yourself warned.
I would have sent this as a private message, but your account isn't set up to receive them.
Michael Dunn
Ranch Hand
Posts: 4632
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
To the OP - don't know if this will help, but it runs OK if you comment out this line
sever oon
Ranch Hand
Posts: 268
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm afraid there are a number of problems with your code, too many for me to address here. But I'll begin with the first classes you listed. Let's take Node first...

This should be stored in a separate file called Node.java from your other class. Just a point of convention, not absolutely necessary, but it will help you keep things straight and get you used to following these conventions.
Next, the Map. This class you wrote has big problems. First, look at the constructors (reformatted for clarity):

Both of these constructors declare local variables, ints placement, size, and arraySize, that are set to zero and immediately go out of scope. If you deleted those lines, it would have no impact whatsoever on your code.
Also, rather than repeat code in different constructors, chain them so you only have to maintain one copy (if you see a change that needs to be made in the logical flow of that code, you don't want to have to go to every constructor you wrote and cut'n'paste the change).
Next, you are using static data and methods throughout the class that should not be static. The data:

The static keyword means that the data (and the methods you've applied it to) are associated with the class, not with *instances* of the class. It's essential for you to understand this to move forward. Picture a class, like your Node class, as a rubber stamp. When you say "new Node(...)", you are using that rubber stamp to stamp out a new object. Understand the relationship between objects and classes. An object is an instance of a class. Lassie is an instance of a Dog. Rover is an instance of a Dog. Red is an instance of a Color.
When you say use the static keyword, you're saying "I don't want this data to be attached to lassie, or rover, or red. I want it to be attached to the class--independent of any one instance. I don't think that's what you want...when you create a map by saying "new Map()", you want all that data to be associated with that map and that map instance alone. Static means that every member of the class shares access to that data:

Now if I write code that creates a bunch of Foo instances in some other part of the project:

After this code executes a.x is 1, b.x is 1, and Foo.s is 2. Note that I referred to s as being a member of the class by saying "Foo.s", not a.s or b.s (those are legal ways to access static data in Java, and unfortunately so because it confuses discussions like this one). All instances of Foo share that variable s. Each instance of Foo carries around its own x, though.
A few more things to consider. Don't carry around redundant data. I notice you have a member variable capacity. You can get this any time you want off of the actual Node[] simply by saying map.length. So this capacity int is unnecessary and only creates more work for you to maintain it. I noticed all those other member variables, head, oldHead, etc, are not used anywhere in your code. Get rid of them.
I admit I'm a little confused with the test app you provided. A map to me is a structure that takes one object, a key, and associates it with another object, a value. For instance, I could use a map to help me associate text and numerical representations:
Integer( 1 ) -> "one"
Integer( 5 ) -> "five"
If I say, get me the value associated with key Integer(10), I'd expect back a String that says "ten". Is this the intention of your map? If so, it doesn't make sense to set up associations between "ape" and "ape"--how do you know if you're map is functioning properly and handing back the value instead of the key?
In any case, go ahead and remove all the statics, put all your classes in different source files, and change your test app to make mappings that will clearly test your data structure. If you still get this NPE calling remove(), check out that first line in which you say map[counter].key != null. If map[counter] refers to a null entry in that array, trying to access key is going to raise an NPE.
So I think you can rewrite your Map class to be quite a bit smaller:

[ February 25, 2004: Message edited by: sever oon ]
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!