在方法 CompareTo(E) 中找不到符号

Cannot Find Symbol at method CompareTo(E)

请帮助一个困惑的新手。我目前正在练习使用 add、remove、contains 和 toString 等方法实现二叉搜索树。我可以实现 class 来处理整数值,但我不知道如何在二叉搜索树上使用泛型。我想灵活一点,也为我的二进制搜索树或我的卡片使用字符串 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;
        }
    }

我遇到一个错误。

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

当我的节点 class 中有 compareTo(E other) 时,为什么找不到 compareTo。我在我的节点 class 中实现了 Comparable 接口,但我不明白为什么。我也试过使用 implements Comparable,但这也行不通。

您正在调用 E 类型中的 compareTo 方法 - 它没有此方法。通过实现接口,你的class继承方法,而不是未知类型参数class。含义:您必须在节点 class.

中创建自定义比较机制

(注意:您也可以检查 E 是否实现了 Comparable,但这更困难,并且在编译期间可能无法实现。)

(注意 2:如果您感到困惑,只需认为 Comparable 意味着实现 class 的实例可以与 E 类型对象进行比较。这甚至不是您想要的实现。)

问题是您已将 E 作为参数传递给 Comparable 但未定义。通常实现 Comparable 的 class,将其自身作为参数传递给 Comparable(作为通用参数)。 Comparable 应该用于比较相同类型的实例。但是,如果您查看您的实现,您并没有比较此 class 的两个实例,您只是将 class 的一个实例与以下 value 行中的另一个实例进行比较=18=]方法:

if (currentRoot.compareTo(value) > 0)

可以看到currentRootNode类型,value是E类型。这是一个错误的实现,因为如果你想拥有类型安全,你不应该一起比较不同类型的值(或者如果你想比较它们,它们永远不应该彼此相等,因为它们具有不同的类型)所以为什么不你只是将这两个 values 相互比较一下?

另一方面 E 是泛型类型,它不仅用于 Node class,E 用于 add 的方法你的 MyTree class 也是。所以 E 应该是 class MyTree 的通用参数,你应该让 MyTree class 的用户决定 E 的确切类型就是他要用MyTreeclass的时候。另一个约束是 E 应该实现 Comparable 因为我们想比较类型 E 的实例。

最后你的class会变成这个:

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;
        }
    }
}