Backwardsman
Backwardsman

Reputation: 151

Why won't this cast?

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

Answers (3)

Kevin Hussey
Kevin Hussey

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

nitishagar
nitishagar

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

Elliott Frisch
Elliott Frisch

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

Related Questions