2012-12-19 24 views
2

我正在寫一個通用最大堆的簡單實現。如果我寫通用類中的java通用鑄造

public class FastMaxHeap<T>{ 

    T[] data; 
    int size; 

    static final int HEAP_SIZE = 10000; 

    @SuppressWarnings("unchecked") 
    public FastMaxHeap(){ 
    data = (T[]) new Object[HEAP_SIZE]; 
    size = 0; 
    } 
} 

它編譯。現在要實際實現堆,即寫入maxHeapify(),我需要能夠比較兩個T。先驗似乎是可能的一種選擇是告訴編譯器T實現了Comparable。但如果我輸入< T>用< T實現Comparable>編譯器抱怨 - 我該如何做?

或者,我可以定義一個類

public class HasValue{ 

    int value; 

    public HasValue(int value){ 
     this.value = value; 
    } 

}

,並在理論上我應該再能比較喜歡x.value> y.value 2個的HasValue對象。但如果我輸入

public class FastMaxHeap<T extends HasValue>{ 

    T[] data; 
    int size; 

    static final int HEAP_SIZE = 10000; 

    @SuppressWarnings("unchecked") 
    public FastMaxHeap(){ 
    data = (T[]) new Object[HEAP_SIZE]; 
    size = 0; 
    } 
} 

我現在得到一個ClassCastException。這裏發生了什麼? Java泛型傷害了我的大腦。

+0

爲什麼不直接存儲'Comparables'? 「Java泛型傷害了我的大腦」+1「 – Perception

+0

+1」。 –

回答

5

在第一種情況下T extends Object在運行時擦除到Object

在第二種情況下T extends HasValue被清除爲HasValue所以你需要有。

data = (T[]) new HasValue[HEAP_SIZE]; 

恕我直言,這是不必要的迂腐在於Java不允許new T[HEAP_SIZE]做你總得去做些什麼。

+1

我刪除了我的答案,贊成你的答案。 – mikeslattery

+0

當T不是HasValue時,你確定會投射嗎? –

+0

@stefanbachert如果新數組的組件類型是T擴展的子類型,則該轉換將工作。 –

0

你可以試試這個(編譯沒有,還)

public class FastMaxHeap<T extends HasValue>{ 

    HasValue[] data; 
    int size; 

    static final int HEAP_SIZE = 10000; 

    public FastMaxHeap(){ 
    data = new HasValue[HEAP_SIZE]; 
    size = 0; 
    } 
} 
+0

如果你放棄鑄造,你不需要壓制警告 –

+0

@Peter Lawrey,刪除 –

0

最好是具有類型令牌來創建這樣

public class FastMaxHeap<T>{ 

    T[] data; 
    int size; 

    static final int HEAP_SIZE = 10000; 

    @SuppressWarnings("unchecked") 
    public FastMaxHeap(Class<T> clazz){ 
    data = (T[])Array.newInstance(clazz, HEAP_SIZE); 
    size = 0; 
    } 
} 

在這種方式數組你將不得不在沒有ClassCastExceptions異常運行時間

還有:< T implements Comparable >是不正確的,正確的是< T extends Comparable >

0

你的堆應該接受一個Comparator < T>作爲構造函數的參數。問題解決了。客戶可以使用他想要的任何類型。您還可以提供一個簡單的重載,它推斷已經實現Comparable的類型T的比較器實現。