2012-10-08 29 views
4

創建一個新的泛型類型數組實踐中,我試圖實現合併排序算法,但試圖實例化泛型類型數組時遇到了非常快的速度。我不完全確定我的計劃是否會奏效,但現在有趣的部分(或令人沮喪,取決於何時問我)是merge()方法的第二行。 newInstance()方法需要知道它應該啓動哪個類,但即使arr1.getClass()編譯得非常好,它在運行時也不起作用。使用Array.newInstance()

public void mergeSort(T[] arr) { 

    T[] merged = merge(Arrays.copyOfRange(arr, 0, arr.length/2), Arrays.copyOfRange(arr, arr.length/2+1, arr.length-1)); 

} 

@SuppressWarnings({"unchecked"}) 
public T[] merge(T[] arr1, T[] arr2) { 
    // A new array of type T that will contain a merged version of arr1 and arr2 
    T[] merged = (T[]) Array.newInstance(arr1.getClass(), arr1.length+arr2.length); 

    int i1 = 0, i2 = 0; 
    for (int i = 0; i < arr1.length + arr2.length; i++) { 
     if (arr1[i1].compareTo(arr2[i2]) < 0) { 
      merged[i] = arr1[i1]; 
      i1++; 
     } else { 
      merged[i] = arr2[i2]; 
      i2++; 
     } 
    } 

    return merged; 
} 

的錯誤信息是:

Exception in thread "main" java.lang.ClassCastException: [[Ljava.lang.String; cannot be cast to [Ljava.lang.Comparable; 
    at sort.SortingAndSearching.merge(SortingAndSearching.java:94) 
    at sort.SortingAndSearching.mergeSort(SortingAndSearching.java:84) 
    at sort.SortingAndSearching.main(SortingAndSearching.java:19) 

回答

14

想我看到的問題......當你這樣做Array.newInstance(...),它的組件類型需要(在你的情況,你希望它是字符串) 。但是,您正在處理數組類(arr1的類型爲String [],並且您正在執行arr1.getClass())。相反,做

arr1.getClass().getComponentType() 

獲得String類出String[]

javadoc

static Object newInstance(Class<?> componentType, int[] dimensions) 

的componentType - 表示新數組

組件類型的Class對象
+1

你是對的!謝謝! –

1

我複製並粘貼了你提供的代碼,甚至沒有編譯。做一些修正後,我來到了這一點:

public class Test { 

    public <T extends Comparable> void mergeSort(T[] arr) { 
    T[] merged = merge(Arrays.copyOfRange(arr, 0, arr.length/2), Arrays.copyOfRange(arr, arr.length/2 + 1, arr.length - 1)); 
    } 

    public <T extends Comparable> T[] merge(T[] arr1, T[] arr2) { 
    // A new array of type T that will contain a merged version of arr1 and arr2 
    T[] merged = (T[]) Array.newInstance(arr1.getClass(), arr1.length + arr2.length); 

    int i1 = 0, i2 = 0; 
    for(int i = 0; i < arr1.length + arr2.length; i++) { 
     if(arr1[i1].compareTo(arr2[i2]) < 0) { 
     merged[i] = arr1[i1]; 
     i1++; 
     } else { 
     merged[i] = arr2[i2]; 
     i2++; 
     } 
    } 
    return merged; 
    } 
} 

由於您使用的是compareTo方法,你必須告訴T實現此接口的編譯器。

+1

是的,我在類聲明中使用'implements Comparable'。 –