Search code examples
javaarrayscastingcomparable

Cannot cast Object to Comparable


I'm trying to order a binary search tree, and store its values on an array, but when I try to convert my ArrayList to array it says I cannot convert an Object to Comparable.

@Override
public T[] postOrder() {
    ArrayList<T> array = new ArrayList<T>();
    postOrder(root, array);
    return (T[]) array.toArray();
}

private void postOrder(BSTNode<T> currRoot, ArrayList<T> array) {
    if (currRoot == null)
        return;
    if (!currRoot.getLeft().isEmpty())
        postOrder((BSTNode<T>) currRoot.getLeft(), array);
    if (!currRoot.getRight().isEmpty())
        postOrder((BSTNode<T>) currRoot.getRight(), array);
    array.add(currRoot.getData());
}

The error message: Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable;

edit: solved that way

public T[] postOrder() {
    ArrayList<T> array = new ArrayList<T>();
    postOrder(root, array);
    return array.toArray((T[]) Array.newInstance(root.getData().getClass(), size()));
}

Solution

  • [Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable;

    This means you are trying to cast Object[] to Comparable[]. (The "[L" means array.)

    toArray returns Object[]. You may be able to use <T>toArray(T[]) instead; however, due to type erasure you cannot do

    //                  cannot do
    //                    vvvvv
    return array.toArray( new T[ mySize ] );
    

    So either

    • Your tree needs a Class<T>.
    • The caller needs to pass a T[] to fill.
    • postOrder needs to return a non-generic array. (Object[]... Comparable[]...)
    • You should return a List<T> instead of a T[].

    I notice you are using @Override so maybe your supertype (interface, superclass) has instructions on how to implement this method. (i.e. if this is homework you should ask your instructor because it is not clear to me which solution you should use.)

    If you happen to have a Class<T>, then you can do

    @Override
    public T[] postOrder() {
        ArrayList<T> array = new ArrayList<T>();
        postOrder(root, array);
        return (T[]) array.toArray(
            java.lang.reflect.Array.newInstance(myClassT, array.size())
        );
    }
    

    Otherwise you need to change the signature of the method.

    See also