0

I'm trying to implement a generic MergeSort sorting algorithm. the function only accepts the type that implements Comparable interface as well as display function takes an array of any type to display the content of the array. But I'm receiving this exception -

Exception in thread "main" java.lang.ClassCastException: java.base/[Ljava.lang.Comparable; cannot be cast to java.base/[Ljava.lang.Integer;

at mergeSort.MergeSort.main(MergeSort.java:10)

My code is below:

package mergeSort;

import java.util.Arrays;

public class MergeSort
{
    public static void main(String[] args)
    {
        Integer[] array = new Integer[]{3, 4, 2, 9, 5, 7, 8, 1, 6};
        display(mergeSort(array));
    }

    public static <T extends Comparable<T>> T[] mergeSort(T[] array)
    {
        if(array.length <= 1) return array;

        int leftLength = array.length/2;
        int rightLength = array.length - leftLength;

        T[] left = (T[]) new Comparable[leftLength];
        T[] right = (T[]) new Comparable[rightLength];

        for(int i = 0; i < array.length; i++)
        {
            if(i < leftLength)
            {
                left[i] = array[i];
            }
            else
            {
                right[Math.abs(left.length-i)] = array[i];
            }
        }

        return merge(mergeSort(left), mergeSort(right));
    }

    public static <T extends Comparable<T>> T[] merge(T[] left, T[] right)
    {
        T[] merged = (T[]) new Comparable[left.length + right.length];

        int i = 0;
        int j = 0;
        int k = 0;

        while(i < left.length && j < right.length)
        {
            if(left[i].compareTo(right[j]) < 0)
            {
                merged[k++] = left[i++];
            }
            else
            {
                merged[k++] = right[j++];
            }
        }

        while(i < left.length) merged[k++] = left[i++];
        while(j < right.length) merged[k++] = right[j++];

        return merged;
    }

    public static <T> void display(T[] array)
    {
        Arrays.stream(array).forEach(value -> System.out.print(value + " "));
        System.out.println();
    }
}
1
  • 1
    In case it wasn't clear, the error is actually saying it couldn't cast Comparable[] (array) to Integer[]. This [Lfoo.Bar; is how Java array types are notated in some places. Commented Feb 12, 2019 at 16:53

1 Answer 1

3

This method declaration promises something it doesn't do:

public static <T extends Comparable<T>> T[] mergeSort(T[] array)

You're not returning T[]. You're returning Comparable[]. So, either just declare it as such:

public static Comparable<?>[] mergeSort(Comparable<?>[] array) { ... }
public static Comparable<?>[] merge(Comparable<?>[] left, Comparable<?>[] right) { ... }

Alternatively, create your arrays using Array.newInstance(). For example:

public static <T extends Comparable<T>> T[] merge(T[] left, T[] right) {
    T[] merged = (T[]) Array.newInstance(
        left.getClass().getComponentType(), 
        left.length + right.length);
    ...
Sign up to request clarification or add additional context in comments.

2 Comments

Now I've this error after I changed type T[] to Comparable<?>[] Error:(50, 39) java: incompatible types: java.lang.Comparable<capture#1 of ?> cannot be converted to capture#2 of ? code is here pastebin.com/DKtRcMVy
Right. Well, you can either revert to using generics but return Comparable<?>[] in your methods, or cast the argument of compareTo to the raw type Comparable: left[i].compareTo((Comparable) right[j])

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.