For practice, I'm trying to implement the merge sort algorithm but got stuck pretty fast when trying to instantiate a generic type array. I'm not entirely sure if my plan will work out, but right now the interesting part (or frustrating, depending on when you ask me) is the second row in the merge() method. The newInstance() method needs to know what class it should initiate as, but even if arr1.getClass() compiles perfectly fine, it won't work during runtime.
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;
}
The error message is:
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)
Think I see the issue... When you do Array.newInstance(...)
, it takes in the component type (in your case, you want it to be String). However, you're handing the array class (arr1 is of type String[], and you're doing arr1.getClass()
). Instead, do
arr1.getClass().getComponentType()
to get the String
class out of String[]
Per javadoc:
static Object newInstance(Class<?> componentType, int[] dimensions)
componentType - the Class object representing the component type of the new array
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With