Reputation: 151
So I have a class:
public static class AVLTreeNode <E extends Comparable<E>> extends BST.TreeNode<E> {
protected int height;
public AVLTreeNode(E e) {
super(e);
}
}
That extends another class:
public static class TreeNode<E extends Comparable<E>> {
protected E element;
protected TreeNode<E> left;
protected TreeNode<E> right;
public TreeNode(E e) {
element = e;
}
}
And I am creating an ArrayList
of type TreeNode
, and trying to cast it to AVLTreeNode
:
public void balancePath(E e) {
ArrayList<TreeNode<E>> path = path(e);
for (int i = path.size() - 1; i >= 0; i--) {
AVLTreeNode<E> a = (AVLTreeNode<E>)(path.get(i));
//continued code not important...
Note that my path method returns an ArrayList
of type TreeNode<E>
. But when I try to cast the node that I get at position i in the list to AVLTreeNode<E>
(a subtype of TreeNode
) I get a ClassCastException
.
What is the problem here?
Edit Here is the full stack trace
Exception in thread "main" java.lang.ClassCastException: com.jeffsite.chapter27.BinarySearchTree$TreeNode cannot be cast to com.jeffsite.chapter29.AVLTree$AVLTreeNode
at com.jeffsite.chapter29.AVLTree.balancePath(AVLTree.java:102)
at com.jeffsite.chapter29.AVLTree.insert(AVLTree.java:19)
at com.jeffsite.chapter29.TestAVLTree.main(TestAVLTree.java:10)
Upvotes: 0
Views: 100
Reputation: 1712
Can you show the path method, this dummy method works:
public ArrayList<? extends TreeNode<E>> path(E e) {
AVLTreeNode<E> tn = new AVLTreeNode<E>(e);
ArrayList<AVLTreeNode<E>> list = new ArrayList<AVLTreeNode<E>>();
list.add(tn);
return list;
}
Upvotes: 0
Reputation: 9403
It depends on the what path returns. If the the path method/func returns a List of TreeNode then the conversion is not possible as the AVLTreeNode has extra params involved.
You can create the ArrayList or List of AVLTreeNode which should help solve the problem at hand (Only in the case path (method) returns the same).
ArrayList<AVLTreeNode<E>> path = path(e);
Upvotes: 0
Reputation: 201439
It isn't a safe thing to cast because it is true that every AVLTreeNode
is a TreeNode
, but it is not necessarily true that every TreeNode
is a AVLTreeNode
. You could your List
only hold AVLTreeNode
(s), by changing from
ArrayList<TreeNode<E>> path = path(e);
to
List<AVLTreeNode<E>> path = path(e);
But I you should program to an interface (that's why List
instead of ArrayList
), so I think you really want
List<TreeNode<E>> path = path(e);
and then you can use
TreeNode<E> a = path.get(i);
And if you must know
if (a instanceof AVLTreeNode) {
// now you can cast a
AVLTreeNode<E> b = (AVLTreeNode<E>) a;
}
Upvotes: 1