4

練習のために、私はマージソートアルゴリズムを実装しようとしていますが、ジェネリック型配列をインスタンス化しようとするとかなり速く動けなくなりました。私の計画がうまくいくかどうかは完全にはわかりませんが、現時点で興味深い部分 (または質問の仕方によってはイライラする部分) は、merge() メソッドの 2 行目です。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)
4

2 に答える 2

16

私は問題を見ていると思います...あなたがそうするときArray.newInstance(...)、それはコンポーネントタイプを取ります(あなたの場合、あなたはそれを文字列にしたいです)。ただし、配列クラスを処理しています (arr1 は String[] 型で、実行していますarr1.getClass())。代わりに、

arr1.getClass().getComponentType()

Stringクラスから抜け出すためにString[]

javadocごと:

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

componentType -新しい配列のコンポーネント型を表す Class オブジェクト

于 2012-10-08T21:43:14.103 に答える
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

于 2012-10-08T21:51:51.003 に答える