1

I have an assignment where the goal is to create a HashTable implementation with generic keys and values. To handle collisions, we were told to use separate chaining. So, I tried doing this:

public class HashTable<K, V> implements Table<K, V> {

    private Node[] generics;

    public class Node {

        V value;
        Node next;

        public Node(V val) {
            value = val;
        }

    }

    public HashTable(int size) {
        generics = (Node[]) new Object[size];
    }

}

For the separate chaining, I wanted to use a linked list implementation (what else), which is why I need generics to hold Node's, not just V's. The reason I cannot just write generics = new Node[size]; is that the Node class contains a generic, and generic array creation is not allowed. For this assignment, this workaround, which produces an "unchecked cast" warning, is acceptable.

Then, in the driver, it tries Table<String, String> ht = new HashTable<String, String>(5); and gets a ClassCastException. There was no ClassCastException when generics was a V[], for context.

So, my question is: How do I create a custom class array, where the custom class contains generics (without changing the driver)?

ZachJH
  • 15
  • 4
  • Just make `generics` an `Object` array and then cast the individual values to `Node` in your get method. But you know an array of `Node`'s is not a Linked List, right? It's still an array. – Matt Feb 18 '20 at 04:13
  • @MattD Yes, it's an array of ```Node```'s. Each one is the head of a Linked List. – ZachJH Feb 18 '20 at 04:18
  • @MattD I tried what you suggested, and it works. However, it creates an "unchecked cast" warning from trying to cast from ```Object``` to ```Node```, and the only compile warning we're allowed is from generic array creation (although ```Node``` itself is not a generic). Thanks for the answer! This solution still seems like bad practice, but it works, and some sort of unchecked cast seems unavoidable. – ZachJH Feb 18 '20 at 04:37

1 Answers1

0

Try below solution

public class HashTable<K, V> {
    private Node<V>[] generics;

    static class Node<V> {
        V value;
        Node next;
        public Node(V val) {
            value = val;
        }
    }
    private HashTable(int size) {
        generics = (Node<V>[]) new Node[size];
    }
}

generics = (Node[]) new Node[size]; this line will give you unchecked cast warning for this code impl check HashMap source code

And if you want to remove unchecked cast warning than you wildcard in generic type reference

 public class HashTable<K, V> {
    private Node<?>[] generics;

    static class Node<V> {
        V value;
        Node next;
        public Node(V val) {
            value = val;
        }
    }
    public HashTable(int size) {
        generics = new Node<?>[size];
    }
 }

it will not give you any "unchecked cast" warning. for this you can HashTable source code

Meet Patel
  • 482
  • 4
  • 12
  • 1
    Thank you very much for this solution. Just a follow-up: Can you explain why the ```Node``` class has to be static? Without the ```static``` keyword the compiler says, "error: generic array creation". – ZachJH Feb 18 '20 at 14:39
  • I am not sure but i think without static `new Node>[size]` will give you error.Reason is this without static you can refer nested class directly `new Node>` – Meet Patel Feb 19 '20 at 05:38
  • if you don't want to use static than use you can create nested class obj like `new HashTable.Node[size]`. Please refer for more details https://stackoverflow.com/q/70324/6582610 – Meet Patel Feb 19 '20 at 05:40