我正在创建一个程序来创建一个包含通用键和通用数据的通用哈希表。当我将数据数组转换为类型Person,我创建的类,并尝试使用getter方法从我的Driver类访问存储在单个Person中的数据时,我得到一个返回的Object类型。我的问题是如何通过泛型类访问非泛型类的信息,因为它存储在通用数组中。
这就是我构建哈希表的方法:
//region Instance Variables
private int count;
private K[] keys;
private E[] data;
private boolean[] hasBeenUsed;
//endregion
//region Constructor
public Table(int capacity)
{
if (capacity <= 0)
throw new IllegalArgumentException("Capacity is negative.");
keys = (K[]) new Object[capacity];
data = (E[]) new Object[capacity];
hasBeenUsed = new boolean[capacity];
}
我的数据获取者(Table
类的一部分):
public E[] getData()
{
return data;
}
public E getDataAt(int index)
{
return data[index];
}
这是我尝试从我的Driver类访问信息的地方:
public void print(Table hash)
{
Person[] people = toArray(hash);
for (int i = 0; i < hash.getData().length; i++)
{
if (null == hash.getKeyAt(i))
System.out.println("NULL AT " + i);
else
System.out.println("Key: " + hash.getKeyAt(i) + " Data: " + hash.getDataAt(i));
}
}
private Person[] toArray(Table hash)
{
Person[] people = new Person[hash.getData().length];
for (int i = 0; i < hash.getData().length; i++)
{
people[i] = hash.getDataAt(i);
}
}
如果需要,这是我的整个Hashtable类:
public class Table<K,E>
{
//region Instance Variables
private int count;
private K[] keys;
private E[] data;
private boolean[] hasBeenUsed;
//endregion
//region Constructors
/**
* Constructor
* Instantiates the keys, data, and hasBeenUsed variables with a passed value of capacity
* @param capacity the size to give the three instance arrays
*/
@SuppressWarnings("unchecked")
public Table(int capacity)
{
if (capacity <= 0)
throw new IllegalArgumentException("Capacity is negative.");
keys = (K[]) new Object[capacity];
data = (E[]) new Object[capacity];
hasBeenUsed = new boolean[capacity];
}
/**
* Constructor
* Default-Sets arrays to size 10
*/
@SuppressWarnings("unchecked")
public Table()
{
keys = (K[]) new Object[10];
data = (E[]) new Object[10];
hasBeenUsed = new boolean[10];
}
//endregion
//region Public Methods
/**
* Put
* Adds a new set to the table
* @param key The new Key value
* @param data the new Data value
* @return null if this is a new set, the old data value if the key already exists
*/
public E put(K key, E data)
{
int index = findIndex(key);
E answer;
if (index != -1)
{
answer = (E) this.data[index];
this.data[index] = data;
return answer;
} else if (count < this.data.length)
{
index = hash(key);
while (keys[index] != null)
{
System.out.println("Collision!");
index = nextIndex(index, key);
}
keys[index] = key;
this.data[index] = data;
hasBeenUsed[index] = true;
count++;
return null;
} else
System.out.println("ERROR IN PUT");
return null;
}
/**
* Remove
* Removes a key-data set from the table
* @return the value removed
*/
@SuppressWarnings("unchecked")
public E remove(K key)
{
int index = findIndex(key);
E answer = null;
if (index != -1)
{
answer = (E) data[index];
keys[index] = null;
data[index] = null;
count--;
}
return answer;
}
/**
* Contains Key
* Checks if the passed key exists
* @param key generic type key to check for
* @return true if the key exists
*/
public boolean containsKey(K key)
{
for (int i = 0; i < data.length; i++)
{
if (hasBeenUsed[i])
{
if (keys[i].equals(key))
{
return true;
}
}
}
return false;
}
/**
* Get
* Retrieves the data held stored with key
* @param key the key to access
* @return the data at key, null if key does not exist
*/
@SuppressWarnings("unchecked")
public E get(K key)
{
int index = findIndex(key);
if (index == -1)
return null;
else
return (E) data[index];
}
//endregion
//region Private Methods
//Locates the index value of key
private int findIndex(K key)
{
int count = 0;
int i = hash(key);
while ((count < data.length) && (hasBeenUsed[i]))
{
if (key.equals(keys[i]))
return i;
count++;
i = nextIndex(i, key);
}
return -1;
}
//Hashes the key
private int hash(K key)
{
return Math.abs(key.hashCode()) % data.length;
}
private int hash2(K key)
{
return 1 + (Math.abs(key.hashCode()) % (data.length-2));
}
//Determines if the next index is valid
private int nextIndex(int i, K key)
{
return (i + hash2(key)) % data.length;
}
//endregion
//region Getters and Setters
public int getCount()
{
return count;
}
public void setCount(int count)
{
this.count = count;
}
public K[] getKeys()
{
return keys;
}
public K getKeyAt(int index)
{
return keys[index];
}
public void setKeys(K[] keys)
{
this.keys = keys;
}
public E[] getData()
{
return data;
}
public E getDataAt(int index)
{
return data[index];
}
public void setData(E[] data)
{
this.data = data;
}
//endregion
}
修改 我编辑了print方法,现在我得到了ClassCastException
以下是我的新print
方法:
public void print(Table<Integer, Person> hash)
{
for (int i = 0; i < hash.getKeys().length; i++)
{
if (null == hash.getKeyAt(i))
System.out.println("NULL AT " + hash.getKeyAt(i));
else
{
System.out.println("Data at key " + hash.getKeyAt(i) + ": \n");
hash.getDataAt(i).printInfo();
}
}
}
答案 0 :(得分:0)
你Table
实际上是通用的。因此,当您想要一个新的Table实例时,您可以说new Table<KEY_TYPE, VALUE_TYPE>()
,它不需要您在任何地方投射。
如果您不确定如何创建泛型类的实例,请检查https://docs.oracle.com/javase/tutorial/java/generics/types.html。