Ivan Syrups
Ivan Syrups

Reputation: 23

Cannot Find Symbol at method CompareTo(E)

Please help a confused novice. I am currently practicing on implementing binary search trees with methods such as add, remove, contains and toString. I can implement the class to work with integer values, but I cannot figure out how to use generics on binary search trees. I wanted to be flexible and also use Strings for my Binary Search Tree, or maybe my Card class.

public class MyTree<E> {

    private class Node implements Comparable<E> {
        private E data;
        private Node left;
        private Node right;
        public Node(E data) {
            this.data = data;
        }
        public int compareTo(E other) { 
            return this.data.compareTo(other); //ERROR HERE 
                                               //(Cannot Find Symbol at method CompareTo(E))
        }
    }

    private Node root;
    private int size;

    public int getSize() {
        return size;
    }

    public void add(E value) {
        this.root = add(value, root);
    }

    private Node add(E value, Node currentRoot) {
        if (currentRoot == null) {
            Node temp = new Node(value);
            size++;
            return temp;
        } else {
            if (currentRoot.compareTo(value) > 0)
                currentRoot.left = add(value, currentRoot.right);
            else if (currentRoot.compareTo(value) < 0)
                currentRoot.right = add(value, currentRoot.right);
            return currentRoot;
        }
    }

I get one error.

return this.data.compareTo(other);
                 ^
symbol: method compareTo(E)
location: variable data of type E
where E is a type-variable:
 E extends object declared in class MyTree

Why isn't compareTo found when I have a compareTo(E other) in my Node class. I implemented the Comparable interface in my Node class, and I can't figure out why. I've also tried using implements Comparable, but that also doesn't work.

Upvotes: 2

Views: 1229

Answers (2)

Tashkhisi
Tashkhisi

Reputation: 2252

The problem is that you have passed E as parameter to Comparable but it is not defined. Generally the class which implements Comparable, pass itself as parameter to Comparable(as generic parameter). Comparable should be used to compare instances of the same type. But if you look at your implementation you are not comparing two instances of this class you are only comparing one instance of your class with the filed value of another instance in the following line of add method:

if (currentRoot.compareTo(value) > 0)

You can see currentRoot is of type Node and value is of type E. Which is a wrong implementation because if you want to have type safety you should not compare values of different type togehter (or if you want to compare them, they should never be equal to each other because they have different type) so why don't you just compare those two values to each other?

On the other hand E is generic type and it is not only for Node class, E is used in the add method of your MyTree class too. So E should be the generic parameter of class MyTree and you should let the user of MyTree class decide what the exact type of E is when he wants to use MyTree class. Another Constraint is that E should implement Comparable because we want to compare instances of type E to each other.

Finally your class will change to this one:

public class MyClassTree<E extends Comparable<E>> {
    private class Node {
        private E data;
        private Node left;
        private Node right;

        public Node(E data) {
            this.data = data;
        }
    }

    private Node root;
    private int size;

    public int getSize() {
        return size;
    }

    public void add(E value) {
        this.root = add(value, root);
    }

    private Node add(E value, Node currentRoot) {
        if (currentRoot == null) {
            Node temp = new Node(value);
            size++;
            return temp;
        } else {
            if (currentRoot.data.compareTo(value) > 0)
                currentRoot.left = add(value, currentRoot.right);
            else if (currentRoot.data.compareTo(value) < 0)
                currentRoot.right = add(value, currentRoot.right);
            return currentRoot;
        }
    }
}

Upvotes: 3

user10992464
user10992464

Reputation:

You are calling a compareTo method within the E type - which doesn't have this method. By implementing the interface, your class inherites the method, not an unknown type parameter class. Meaning: You have to create the custom comparing mechanics in the Node class.

(Note: you can also check if E implements Comparable, but it is more difficult, and might not be possible during compilation-time.)

(Note 2: If you are confused, just think that Comparable means that instances of the implementing class can be compared to E type objects. This isn't even the implementation you want.)

Upvotes: 1

Related Questions