8

Possible Duplicate:
Java how to: Generic Array creation
Error generic array creation

I have been tasked with writing a Hash Table in Java, which must work with any data type. The rules on the code I am writing are as follows: - The hash table must have an array as the underlying data structures, of a size determined at the time the object is constructed - When a collision occurs, the element that collides should be placed into a linked list, which holds all of the elements at that index (key) in the hash table

Thus, for the underlying data type, I have made an array of type LinkedList (custom, not the Java API LinkedList).

private LinkedList<T>[] table;

The issue is, of course, instantiating this array. Here are some of my attempts:

public HashTable(int size) {
  table = new LinkedList<T>[size];
}

This throws a compile-time generic array creation error.

public HashTable(int size) {
  table = (LinkedList<T>[])(new Object[size]);
}

That causes a ClassCastException error at runtime (java.lang.Object cannot be cast to LinkedList).

The person heading the project is also unsure of how to deal with this issue. Is there any way I can change my code so that the hash table still has an array as its underlying data structure with the collisions being placed in a LinkedList?

6
  • 1
    See if stackoverflow.com/questions/3903196/… helps you Commented Nov 7, 2011 at 23:52
  • 1
    Another reason why whoever thought type erasure was a good way to implement generics should be shot. Commented Nov 8, 2011 at 0:00
  • If this is homework, please mark it as such. Commented Nov 8, 2011 at 0:12
  • @DavidZaslavsky, it seems that we've decided to use the solution proposed in the problem that you've posted a link to, using an ArrayList as the Collection. Thank you very much, and I need to work on my searching skills. Commented Nov 8, 2011 at 0:33
  • I find it impossible to believe this isn't homework. Commented Nov 8, 2011 at 1:59

3 Answers 3

7

This worked for me:

public class HashTable<T> {

    private LinkedList<T> table[];

    @SuppressWarnings("unchecked")
    public HashTable(int size) {
        table = new LinkedList[size];
    }

}

For example:

HashTable<String> t = new HashTable<String>(10);
t.table[0] = new LinkedList<String>();
t.table[0].add("test");
System.out.println(t.table[0].get(0));

Yes, the constructor generated a warning (that explains the "unchecked" annotation), but afterwards the code works without more warnings.

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

Comments

1

Just use Object[] as your data store, and manually cast it to the specific type. This is acceptable in building infrastructure stuff, where type relations can be harder than usual.

For what it's worth, this is the way to create generic array in Java:

@SafeVarargs
static <E> E[] newArray(int length, E... array)
{
    return Arrays.copyOf(array, length);
}

//used in your example

    private LinkedList<T>[] table;

    public HashTable(int size) {
        table = newArray(size);
    }

Comments

0

It isn't ideal, but you can do this sort of thing:

import java.util.LinkedList;

public class Test
{
    static class HashTable<T>
    {
        public HashTable(int size)
        {
            LinkedList<T>[] table = (LinkedList<T>[])java.lang.reflect.Array.newInstance(LinkedList.class, size);
        }
    }

    public static void main(String[] args)
    {
        HashTable<Integer> table = new HashTable<Integer>(23);
    }
}

2 Comments

Class -> Class<T> and don't trap and drop Exception e. And why not just pass LinkedList.class to newInstance? You don't need the forName lookup at all.
Array.newInstance(LinkedList.class, size) is exactly identical to new LinkedList[size]

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.