Reputation: 23
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
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
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