2014-04-13 119 views
0

我有以下代碼:這個Java泛型代碼爲什麼不能正常工作?

public abstract class Heap { 

    Comparable<?> data[]; 

    int count, size; 

    public Heap(int size) { 

     this.size = size; 

     data = new Comparable<?>[ size + 1 ]; 

     this.count = 0; 
    } 

    public abstract void insert(Comparable<?> item); 

} 

class MinHeap extends Heap { 

    public MinHeap (int size) { super(size); } 

    public void insert(Comparable<?> item) { 

     //this line here is giving me an error 
     //due to how I am storing the array in Heap 

     int k = data[ 0 ].compareTo( item); 

    } 
} 

線上面指出的是給我這個錯誤:The method compareTo(capture#1-of ?) in the type Comparable<capture#1-of ?> is not applicable for the arguments (Comparable<capture#2-of ?>)。我無法找到一種方法在保持這些條件的同時使其工作:1)我希望MinHeap能夠處理任何實現了Comparable的數據,2)我不想將預先初始化的數組傳遞給構造函數。我這樣說是因爲我不希望做到以下幾點:

abstract class Heap< T extends Comparable<T> > { 

     T data[]; 

     public Heap(T data[], int size) { 

      this.data = data; 
    //I do not want to have to pass an instantiated array. 
    //I want the constructor to handle the instantiation. If I do this I know the issue with the 
    //compareTo will be solved, but I really prefer to avoid this. 
     } 

} 

我的問題是這樣的:在我的代碼,爲什麼我收到此錯誤?除了第二個例子中描述的方式之外,有沒有人知道一種方式?我希望能夠用任何可比較的數據創建最小堆數據結構。全部有幫助評論感謝。謝謝。

注意:不要擔心實例變量的訪問修飾符。爲簡單起見,我將它們作爲默認值。我知道他們應該是私人的,或者是保護者。

+0

第二個解決方案似乎是要走的路。你可以嘗試這樣的事情(但我不知道是否有可能這樣):data =(T [])Array.newInstance(data.getClass()。getComponentType(),size); – George

回答

1

首先,這段代碼是創建一個通用的陣列無效:

data = new Comparable<?>[ size + 1 ]; 

This link in the Java Trails解釋了爲什麼它是非法的,但它歸結爲一個事實,即數組必須知道在編譯它的類型,泛型的工作基於類型擦除,並可以在運行時推斷。

但是在我們解決這個問題之前,您的泛型有一個問題 - 它們並不是真正的泛型。你只在這裏使用通配符泛型,沒有界限。

如果你想讓你的抽象類有一個充滿Comparable的泛型數組,那麼你想讓你的抽象類綁定到Comparable<T>,並且你的數據只需綁定到T。有了這個,我們終於可以解決這個數組初始化成編譯(但選中鑄)形式:

data = (T[]) new Comparable[size + 1]; 

下面是引用完整的類。它的關閉你的第二種形式,並不需要你傳入一個實例化的數組。此外,由於T綁定到Comparable<T>,我們不需要在方法中聲明它爲參數 - 我們可以簡單地提供T

public abstract class Heap<T extends Comparable<T>> { 
    T data[]; 
    int count, size; 

    public Heap(int size) { 
     this.size = size; 
     data = (T[]) new Comparable[size+1]; 
     this.count = 0; 
    } 

    public abstract void insert(T item); 

} 

對於該示例,您還需要將泛型類型添加到您的子類,以及:

class MinHeap<T extends Comparable<T>> extends Heap<T>  
+0

最好的做法是檢查演員是否與T相當? –

+0

這樣做有點棘手,因爲直到運行時才知道'T'是什麼類型。它可能是一個未經檢查的轉換,但已知這是創建通用數組的方式。如果可以的話,爲什麼不使用'List '而不是? – Makoto

0

您的數據可以包含任何類型的對象,只要它的類實現了Comparable即可。所以你可以在你的數組中包含字符串,整數,長整數或者香蕉。

並將整數與字符串或與香蕉比較沒有意義。這就是編譯器不讓你編譯這段代碼的原因。

第二種方法是正確的。您可以在內部使用一組對象,並將每個對象投射到一個T。如果你所有的方法只接受T的實例,那麼演員陣容保證成功。或者你可以使用List,它比數組更通用。

1

試試這個:

  • 首先compareTo()返回intboolean值。
  • public abstract void insert(Comparable<?> item);是錯誤的。
  • 如果使用泛型而不是靜態數組,則使用List。欲瞭解更多信息閱讀How to create a generic array?

示例代碼:

abstract class Heap<T> { 
    List<Comparable<T>> data; 

    public Heap(int size) { 
     data = new ArrayList<Comparable<T>>(); 
    } 

    public abstract void insert(T item); 
} 

class MinHeap<T extends Comparable<T>> extends Heap<T> { 

    public MinHeap(int size) { 
     super(size); 
    } 

    public void insert(T item) { 
     int k = data.get(0).compareTo(item); 
    } 
} 
相關問題