-1

I am writing a hash table which uses generic class, but this line shows a null pointer exception. Is my way of calling the element wrong?

table[hashVal].tableKey = key;

Here is the entire code

public class LinearProbingHashTable<K, V> {
// initialize size of table and entry counter
int size = 13;
int entryCounter = 0;
// create an entry
private static class Entry<K, V> {
    K tableKey;
    V tableValue;
    String status;
}       

Entry<K, V> table[] = new Entry[size];
// insert new entry into table
public boolean insert(K key, V value) {
    // throw exception if key is null
    if ( key == null ) {
        throw new IllegalArgumentException("Invalid key");
    }
    // rehash if the table is half full
    if ( entryCounter >= ( size / 2) ) {
        rehash();
    }
    // return false if duplicate
    for ( int i = 0; i < table.length; i++ ) {
        if ( table[i] != null) {
            if ( table[i].tableValue.equals(value) == true )
                return false;
        }
    }
    // calculate hash value
    int hashVal = 0;
    String keyToString = key.toString();
    for ( int i = 0; i < keyToString.length(); i++ ) {
        hashVal = 37 * hashVal + keyToString.charAt(i);
    }
    hashVal %= size;
    if ( hashVal < 0 )
        hashVal += size;
    // if entry is empty, insert key and value into the table and return true
    if ( table[hashVal] == null) {
        table[hashVal].tableKey = key;
        table[hashVal].tableValue = value;
        entryCounter++;
        return true;            
    }
    // element collision
    else {
        // linear probing
        for ( int i = hashVal + 1; i < table.length; i++ ) {
            // if probe reaches end, restart from 0
            if ( table[i] == null )
                i = 0;
            // if entry is empty, insert key and value and return true
            if ( table[i].tableKey == null ) {
                table[i].tableKey = key;
                table[i].tableValue = value;
                entryCounter++;
                return true;
            }
        }
    }
    return false;               
}

public V find(K key) {
    // look for the key
    for ( int i = 0; i < table.length; i++ ) {
        // if key is found, return its value
        if ( table[i].tableKey.equals(key) == true )
            return table[i].tableValue;
    }
    // if key is not found, return null
    return null;

}

public boolean delete(K key) {
    // look for the key
    for ( int i = 0; i < table.length; i++) {
        // if key is found, change entry's status and return true
        if ( table[i].tableKey.equals(key) == true) {
            table[i].status = "deleted";
            return true;
        }
    }
    // if key is not found, return false
    return false;
}

private void rehash() {

    size = size * 2;




}

public int getHashValue(K key) {
    // search the table
    for ( int i = 0; i == table.length; i++) {
        // if the key exists, exit the loop
        if ( table[i].tableKey.equals(key) == true )
            break;
        // if key is not in the table, return -1
        else if ( table[i].tableKey.equals(key) == false && i == table.length )
            return -1;
    }
    // calculate 
    int hashVal = 0;
    String keyToString = key.toString();
    for ( int i = 0; i < keyToString.length(); i++ ) {
        hashVal = 37 * hashVal + keyToString.charAt(i);
    }
    hashVal %= size;
    if ( hashVal < 0 )
        hashVal += size;
    return hashVal;

}

public int getLocation(K key) {
    // search for the key
    for ( int i = 0; i < table.length; i++) {
        // return its position if found
        if ( table[i].tableKey.equals(key) == true)
            return i;           
    }
    // if not found, return -1
    return -1;
}

public String toString() {
    int i = 0;
    // call recursive function
    return toString(i); 
}
// print string recursively
private String toString(int i) {
    // return blank at the end of the table
    if ( i == table.length )
        return "";
    // print null when entry is empty
    if ( table[i].tableValue.equals(null) == true)
        System.out.println(i + " " + "null");
    // print value
    else
        System.out.println(i + " " + table[i].tableValue);
    i++;
    return toString(i);
}

public static void main(String[] args) {

    LinearProbingHashTable<Object, Object> hashTable = new LinearProbingHashTable<>();

    hashTable.insert("test", 234);

}


}
Jin
  • 1

1 Answers1

0

Here you guaranteed to get the null pointer exception:

if ( table[hashVal] == null) {
    table[hashVal].tableKey = key;

First you need to create an entry object at that position, and then you can set the fields of the entry:

if ( table[hashVal] == null) {
    table[hashVal] = new Entry<K, V>();
    table[hashVal].tableKey = key;
jas
  • 10,715
  • 2
  • 30
  • 41
  • Great. That was really helpful. So I need to create an entry before using that space? – Jin Mar 25 '15 at 04:29
  • So the statement "LinearProbingHashTable hashTable = new LinearProbingHashTable<>();" does not create it automatically? – Jin Mar 25 '15 at 04:30
  • It doesn't. It creates the array via the declaration `Entry table[] = new Entry[size];`. But that only creates an array with _room_ for `size` elements, with each element itself initialized to null. In other words, the array is created "automatically", but it's empty until you create Entry objects to put inside it. – jas Mar 25 '15 at 08:49