Search code examples
javagenericscomparable

Using compareTo function in a generic class in Java causes [Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable


I'm facing an exception: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable; while I try to use the compareTo function in my generic class.

Here is my code and I'm facing this issue in the function of insert():

public class BinaryTreeArray<T extends Comparable<T>>{
T[] array;
int level, count;
final int capacity;

public BinaryTreeArray(int size)
{
    capacity=size;
    array=(T[]) new Object[capacity];

    for(int i=0; i<capacity; i++)
        array[i]=null;
}

public BinaryTreeArray(T val, int size) //val is the root in this case 
{
    capacity=size;
    array=(T[]) new Object[capacity];
    array[0]=val;
    count=0;

    for(int i=1; i<capacity; i++)
        array[i]=null;
}

public void insert(T x)
{
int currentIndex = 0;
System.out.println("Adding: "+x);
while(true) {
    if(array[currentIndex]==null)
    {
        array[currentIndex]=x;
        System.out.println(" Inserted at index: "+currentIndex);
        break;
    }
    else if(array[currentIndex].compareTo(x)<=0) 
    {
        if(array[currentIndex] == x){
            System.out.println("ERROR!-- Repeating element" );
            break;
        }else
        System.out.print(" Right ");
        currentIndex =(2*currentIndex) + 2;
    }
    else if(array[currentIndex].compareTo(x)>=0)
    {
         if(array[currentIndex] == x){
            System.out.println( "ERROR!-- Repeating element");
            break;
        }else
        System.out.println(" Left ");
        currentIndex=1+(2 * currentIndex);
    }

  }
 }
}

Any help would be appreciated. Thank you.


Solution

  • Since the erasure of T is Comparable, not Object, you can't create an Object[] and cast it to a T[].

    Create a Comparable[] instead.

    array=(T[]) new Comparable[capacity];
    

    However, you don't really need to constrain your class to naturally comparable types: if you also pass a Comparator<? super T> to the constructor, and store that in a field to use when you compare elements, you can accept any type.

    array[currentIndex].compareTo(x)
    

    Would become

    comparator.compare(array[currentIndex], x)
    

    That would remove the upper bound extends Comparable<T> from T, and allow your Object[] array creation to work.