使用Array.newInstance()创建新的泛型类型数组

时间:2012-10-08 21:38:50

标签: java mergesort

对于练习,我正在尝试实现合并排序算法,但在尝试实例化泛型类型数组时卡住的速度非常快。我不完全确定我的计划是否会成功,但现在有趣的部分(或令人沮丧的,取决于你何时问我)是merge()方法的第二行。 newInstance()方法需要知道它应该启动哪个类,但即使arr1.getClass()编译完全正常,它也不会在运行时运行。

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)

2 个答案:

答案 0 :(得分:15)

认为我看到了问题...当你执行Array.newInstance(...)时,它会接收组件类型(在您的情况下,您希望它是String)。但是,您正在处理数组类(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实现此接口。