2014-02-16 45 views
1

我正在構建一個通用HashTable類,在該類中我們使用簡單的Java .hashCode()方法將鍵轉換爲哈希,以數組大小爲模,並將結果存儲在索引中。唯一的問題是,教授希望我們不僅存儲價值,而且還存儲我們摧毀的關鍵。爲此,我創建了一個Data類,用於存儲並獲取兩個值:通用數組非常規鑄造

private class Data { 
    private K key; 
    private V value; 

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

    public K getKey() { 
     return key; 
    } 

    public V getValue() { 
     return value; 
    } 
} 

很簡單的東西。當我嘗試創建數據項的數組以保存創建它們的哈希值和鍵時,會遇到困難。 K和V都在哈希表類聲明中指定的通用值:

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

當我第一次創建的類,我只是用一個對象陣列上的投創造的五世的數組,但由於我們需要存儲這兩個值,我決定創建Data類並存儲它們。但是,當我與我的

hashArray = (Data[])new Object[arraySize]; 

嘗試它給我的錯誤

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Lproject3.HashTable$Data; 

這讓我無法創建類型數據的數組。有沒有另一種方式,我可以存儲這個沒有使用列表(因爲這是一個賦值的參數)?

+1

考慮看着java.util.HashMap'的'執行和檢查,看他們如何處理它。 –

回答

4

Object[]不是Data[]。投射在運行時必然會失敗。但由於該類型已在那裏已知,爲什麼不直接創建Data[]?創建一個Object[]沒有意義,並試圖施展它。

現在回答你的其他問題,下面的鑄造:

V[] arr = (V[]) new Object[arraySize]; 

作品,因爲V類型不會在運行時知道。類型信息被刪除。而且,由於類型參數的擦除是它的最左邊的束縛,這是在這種情況下Object,在運行時間超過鑄看起來是這樣的:

Object[] arr = (Object[]) new Object[arraySize]; 

似乎很好,不是嗎?然而,這種方式也將盡快爲你讓陣列逃脫類失敗,返回值分配給任何這樣的引用:

HashTable<String, Integer> map = new HashTable<String, Integer>(); 
// suppose you have a getter to get the array stored 
Integer[] arr = map.getValueArray(); 

第二行上面會在運行時拋出ClassCastException出於同樣的原因如上所述。所以,只有在你不讓數組逃脫課程時,才能使用Object[]V[]

現在,考慮另一種情況,例如您給V的綁定,比如說V extends Comparable<V>,看看會發生什麼;

public class MyClass<T extends Comparable<T>> { 
    T[] arr; 

    public MyClass() { 
     arr = (T[])new Object[0]; 
    } 
} 

在這種情況下,類型參數T的擦除爲Comparable,所以在構造函數中投擦除:

arr = (Comparable[]) new Object[0]; 

,這將再次拋出ClassCastException,您是否不讓該數組轉義類。

所以,重點是,你需要在創建一個泛型類型數組的時候非常小心。


參見: