0

I got the following exception in my code:

java.lang.ClassCastException: [Ljava.lang.Comparable; cannot be cast to [Ljava.lang.Integer; at the following method:

public static void comprobar() {
    Integer a1[] = crearAleatorioInteger(100000);
    Integer a2[] = Arrays.copyOf(a1, a1.length);
    Ordenacion.quickSort(a1);
    a2 = Ordenacion.mergeSort2(a2); //Here is where the exception is thrown
    if(Ordenacion.sonIguales(a1,a2)) System.out.println("Bien");
    else System.out.println("Mal");
}

I guess the mistake must be in the method mergeSort2() which is in the class Ordenacion, it is the following:

public static <T extends Comparable<T>> T[] mergeSort2(T[] v) {
    return mergeSort2(v, 0, v.length - 1);
}
private static <T extends Comparable<T>> T[] mergeSort2(T[] v, int i, int f){
    if (f - i <= 1) {
        T[] res = (T[]) new Comparable[f-i+1];
        if(f==i) res[0] = v[i];
        else if (v[i].compareTo(v[f]) > 0){
            res[0] = v[f];
            res[1] = v[i];
        }
        else{
            res[0] = v[f];
            res[1] = v[i];
        }
        return res;
    }
    else{
        int m = (i + f) / 2;
        return merge2(mergeSort2(v, i, m),mergeSort2(v, m + 1, f));
    }
}
private static <T extends Comparable<T>> T[] merge2(T[] v1, T[] v2){
    int a = 0, b = 0, k = 0;
    T[] res = (T[]) new Comparable[v1.length+v2.length];
    while(a < v1.length && b < v2.length){
        if (v1[a].compareTo(v2[b]) < 0) res[k++] = v1[a++];
        else res[k++] = v2[b++];
    }
    while (a < v1.length) res[k++] = v1[a++];
    while (b < v2.length) res[k++] = v2[b++];
    return res;
}

Thank you for any help you may offer

2 Answers 2

2

You are creating the wrong array type and casting it to a "T[]" here...

T[] res = (T[]) new Comparable[f-i+1];

You need to create an array of type T which is not that straightforward.

As there is no way to find out the actual type of a generic type variable at runtime, you might have to do something like this...

public static <T extends Comparable<T>> T[] mergeSort2(T[] v, Class<T> type) {
    return mergeSort2(v, 0, v.length - 1, type);
}

private static <T extends Comparable<T>> T[] mergeSort2(T[] v, int i, int f, Class<T> type){
    if (f - i <= 1) {
        T[] res = (T[]) Array.newInstance(type, f-i+1);
        ...

UPDATE:

As @pbabcdefp pointed out, you don;t need to pass around the "Class" parameter. You can use this instead...

        T[] res = (T[]) Array.newInstance(v.getClass().getComponentType(), f-i+1);

This only works for arrays, if you had a List, you won't be able to get the type...

Sign up to request clarification or add additional context in comments.

5 Comments

In this case you don't need to pass a Class<T> as you can use v.getClass().getComponentType().
@pbabcdefp - true, I forgot that this works for Arrays (and I even answered a question like this earlier!!)
It now says "cannot find symbol - method newInstance(java.lang.Class<capture#1 of ?>, int)
@JOSEMAFUEN - You are importing the "right" Array right? java.lang.reflect.Array
Thank u so much, now it works. Though it doesn't give me the right answer at leasts there are no exceptions hahaha
0

You create an array of Comparable here:

T[] res = (T[]) new Comparable[f-i+1];

and try to cast it to Integer[]. Which is obviously wrong, since Comparable is no subclass of Integer and thus the cast cannot be performed. You'll have to create a new array of type T.

4 Comments

"You'll have to create a new array of type T" and how can we do that?
That is not the line that throws the exception.
What @pbabcdefp means is that at runtime generics will be erased so T[] res = (T[]) new Comparable[f-i+1]; where <T extends Comparable<T>> is equivalent of Comparable[] res = (Comparable[]) new Comparable[f-i+1]; which means that it can't throw this exception. Problem OP is having is here a2 = Ordenacion.mergeSort2(a2); where we are trying to assign Comparable[] to Integer[]. Solution to this problem is in fact creation of array of T type, but new T[] is not valid (because of type erasure) so it would be good to add in your answer proper solution of this problem.
@pbabcdefp this is where the exception is thrown. op just didn't post the full stacktrace but the least important part of it. @Pshemo `(T[]) Arrays.newInstance(Class<T> , int)' could create a 'T[]' downside: you need to provide the class of 'T'.

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.