Java Generics: Array containing generics [duplicat

2020-03-02 03:24发布

问题:

This question already has answers here:
Closed 8 years ago.

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?

回答1:

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.



回答2:

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);
    }


回答3:

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);
    }
}