Java泛型:compareTo和“;捕获&x201D;

Java泛型:compareTo和“;捕获&x201D;,java,generics,binary-tree,comparable,Java,Generics,Binary Tree,Comparable,我正在尝试编写一个二进制树的实现,它的对象可以是实现Comparable的任何类型。然而,我意识到这并不完全有效。例如,字符串和Double不能插入到同一个树中,即使它们都实现了compariable 因此,我想知道是否有可能编写这样的代码,即二进制树可以用任何类型实现Comparable的值实例化,但是添加到树中的任何后续元素都必须与根的值共享相同的超类型 以下是我目前掌握的代码: public class BinaryTree { private Node root; p

我正在尝试编写一个二进制树的实现,它的对象可以是实现
Comparable
的任何类型。然而,我意识到这并不完全有效。例如,字符串和Double不能插入到同一个树中,即使它们都实现了
compariable

因此,我想知道是否有可能编写这样的代码,即二进制树可以用任何类型实现
Comparable
的值实例化,但是添加到树中的任何后续元素都必须与根的值共享相同的超类型

以下是我目前掌握的代码:

public class BinaryTree {

    private Node root;

    public BinaryTree() {

        this.root = null;
    }

    public Node lookup(Comparable<Object> value) {

        return lookup(this.root, value);
    }

    private Node lookup(Node node, Comparable<Object> value) {

        Node match = null;

        if (match != node) {

            if (value == node.value) {
                match = node;
            } else if (value.compareTo(node.value) < 0) {
                return lookup(node.left, value);
            } else {
                return lookup(node.right, value);
            }
        }

        return match;
    }

    public Node lookupNonRecursively(Comparable<Object> value) {

        return lookupNonRecursively(this.root, value);
    }

    private Node lookupNonRecursively(Node node, Comparable<Object> value) {

        Node match = null;

        if (match != node) {

            if (value == node.value) {
                match = node;
            } else {

                Node root = node;
                boolean found = false;

                while (!found && root != null) {

                    if (root.value.compareTo(value) < 0) {

                        if (root.left == null) {

                            root.left = match = new Node(value);
                            found = true;
                        } else {
                            root = root.left;
                        }
                    } else {
                        if (root.right == null) {

                            root.right = match = new Node(value);
                            found = true;
                        } else {
                            root = root.right;
                        }
                    }
                }
            }
        }

        return match;
    }

    public Node insert(Comparable<Object> value) {

        return insert(this.root, value);
    }

    private Node insert(Node node, Comparable<Object> value) {

        if (node == null) {
            node = new Node(value);
        } else {
            if (node.value.compareTo(value) <= 0) {
                insert(node.left, value);
            } else {
                insert(node.right, value);
            }
        }

        return node;
    }

    public Node insertNonRecursively(Comparable<Object> value) {

        return insertNonRecursively(this.root, value);
    }

    private Node insertNonRecursively(Node node, Comparable<Object> value) {

        if (node == null) {
            node = new Node(value);
        } else {

            Node root = node;
            boolean inserted = false;

            while (!inserted) {

                if (node.value.compareTo(root.value) < 0) {

                    if (root.left == null) {
                        root.left = node = new Node(value);
                        inserted = true;
                    } else {
                        root = root.left;
                    }
                } else {
                    if (root.right == null) {
                        root.right = node = new Node(value);
                        inserted = true;
                    } else {
                        root = root.right;
                    }
                }
            }
        }

        return node;
    }

    public static class Node {

        private Node left;
        private Node right;
        private Comparable<Object> value;

        public Node(Comparable<Object> value) {

            this.left = null;
            this.right = null;
            this.value = value;
        }
    }
}

您可以看到,我为这个类实现了一些不同的
BinaryTree
方法,但是需要应用相同的规则:传递到
lookup()
insert()
的任何值也需要共享根的超类型。我有一种感觉,这是一些
的变体使二叉树像

public class BinaryTree<T extends Comparable<T>>{
   ...
}
其中
MyClass
必须实现
compariable
,即可与同一类的对象进行比较

您的方法如下(示例):


这同样适用于
节点
类。以同样的方式使其通用。

使您的二叉树像

public class BinaryTree<T extends Comparable<T>>{
   ...
}
其中
MyClass
必须实现
compariable
,即可与同一类的对象进行比较

您的方法如下(示例):


这同样适用于
节点
类。以同样的方式使其通用。

如果您只是尝试
?如果您只是尝试
?为了获得最佳效果,请使用
@newacct,这是因为超类型为T的任何类型也可以使用该树吗?@lilitutos27:是的。我不确定你的意思,但例如,如果
类动物实现Compariable
,并且
类狗扩展了Animal
,那么
将与另一个
(以及其他动物)相比较,但是
将不满足原始边界,因为
Dog
不是
compariable
的子类型
Comparable
对于
T
而言纯粹是一个“消费者”,因此根据PECS规则,它应该始终与
super
有界通配符一起使用。为了获得最佳结果,请使用
@newacct,这是因为超类型为T的任何类型也可以使用树吗?@Lilitustos27:是的。我不确定你的意思,但例如,如果
类动物实现Compariable
,并且
类狗扩展了Animal
,那么
将与另一个
(以及其他动物)相比较,但是
将不满足原始边界,因为
Dog
不是
compariable
的子类型
Compariable
纯粹是关于
T
的“消费者”,因此根据PECS规则,它应始终与
超级
有界通配符一起使用。
public class BinaryTree<T extends Comparable<T>>{
   ...
}
new BinaryTree<MyClass>();
 public Node lookup(T value) { ... }