Reputation: 35
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()));
}
Upvotes: 2
Views: 4755
Reputation: 37845
[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
Class<T>
.T[]
to fill.postOrder
needs to return a non-generic array. (Object[]
... Comparable[]
...)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
Upvotes: 4
Reputation: 46470
Generic arrays are messy, you need to call the other toArray()
method:
public T[] postOrder(T[] result) {
ArrayList<T> array = new ArrayList<T>();
postOrder(root, array);
return array.toArray(result);
}
It doesn't matter what size the result is, just make sure you don't use later what you passed in, because it may get reallocated inside toArray
if the size is not correct, so use only the return value of postOrder
.
Consider that it's probably much much more cleaner if you just return List<T>
, and let the caller take care of converting it to an array! Notice how much less explanation is needed for returning a List
...
public List<T> postOrder() {
ArrayList<T> array = new ArrayList<T>();
postOrder(root, array);
return array;
}
Upvotes: 2