3

I'm trying to implement a generic HashMap, but for some reason the java compiler will not allow me to return the proper generic type.

Here is my HashMap code:

public class SimpleHashMap<K,V> {
  private int tableSize;
  private HashEntry[] table;

  public SimpleHashMap(){
    table = new HashEntry[tableSize];
    for(int i = 0; i < table.length; i++){
      table[i] = null;
    }
  }

  public V put(K key, V value){
    int keyIndex = getHashCode(key);
    if(table[keyIndex] == null){
      table[keyIndex] = new HashEntry<K, V>(key, value);
    }
    else{
      table[keyIndex] = new HashEntry<K, V>(key, value, table[keyIndex]);
    }
    return value;
  }

  public V get(K key){
    int keyIndex = getHashCode(key);
    if(table[keyIndex] == null){
      return null;
    }
    else{
      HashEntry temp = table[keyIndex];
      while(temp != null){
        if(temp.key.equals(key)){
          return temp.value;
        }
        temp = temp.next;
      }
    }
  }

  public int getHashCode(K key){
    return key.hashCode() % tableSize;
  }
}

Here is my HashEntry code:

public class HashEntry<K,V>{
  public K key;
  public V value;
  public HashEntry next;

  public HashEntry(K key, V value){
    this(key, value, null);
  }

  public HashEntry(K key, V value, HashEntry next){
    this.key = key;
    this.value = value;
    this.next = next;
  }
}

The only error I get at compile time is:

error: incompatible types: Object cannot be converted to V
          return temp.value;
                     ^
  where V is a type-variable:
    V extends Object declared in class SimpleHashMap

I've tried explicitly casting it, but it still refuses to return a object of type V.

2
  • I believe your HashEntry temp should have type parameters <K,V> Commented Oct 25, 2015 at 9:33
  • In fact all your HashEntry references in SimpleHashMap should use <K,V> since HashEntry is not an inner class of SimpleHashMap Commented Oct 25, 2015 at 9:34

2 Answers 2

2

You need to declare your temp variable with type like this:

HashEntry<K,V> temp = table[keyIndex];

Your get method can be updated as follows:

public V get(K key){
        int keyIndex = getHashCode(key);

        if(table[keyIndex] == null){
          return null;
        }
        else{
          HashEntry<K,V> temp = table[keyIndex];          
          while(temp != null){
            if(temp.key.equals(key)){
              return temp.value;
            }
            temp = temp.next;
          }
          return temp.value;
        }

      }
Sign up to request clarification or add additional context in comments.

Comments

1
  HashEntry temp = table[keyIndex];

HashEntry is a generic type, but you are using it without type information.

If you want to use it like that, you have to make HashEntry a non-generic inner class and re-use the outer class type bounds.

public class HashEntry{ // has to be inside SimpleHashMap
  public K key; // <-- type variables from
  public V value; // <-- SimpleHashMap
  public HashEntry next;

  public HashEntry(K key, V value){
    this(key, value, null);
  }

  public HashEntry(K key, V value, HashEntry next){
    this.key = key;
    this.value = value;
    this.next = next;
  }
}

The other possibility is to leave HashEntry as it is and change the line to

  HashEntry<K, V> temp = table[keyIndex];

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.