Search code examples
javagenericscomparable

Comparable types (objects) can't be compared


I am getting this mystical error:

The operator > is undefined for the argument type(s) java.lang.Comparable, java.lang.Comparable

What the heck?

(here's the code)

public class BST<T extends Comparable<T>> {
    public static class Node<P extends Comparable<P>> {
        P val;
        Node<P> left;
        Node<P> right;

        public Node() {

        }

        public Node(P val) {
            this.val = val;
        }
    }

    Node<T> root;

    private void addValHelper(Node root, Node newNode) {
        if (root.val > newNode.val) { // <-- ERROR IS HERE
            if (root.left == null) {
                root.left = newNode;
            } else {
                addValHelper(root.left, newNode);
            }
        } else {
            if (root.right == null) {
                root.right = newNode;
            } else {
                addValHelper(root.right, newNode);
            }
        }
    }
}

Solution

  • Java doesn't have operator overloading. You can't compare Comparable types with >. You need to use root.val.compareTo(newNode.val) instead.

    As an aside:

    • Comparable is an interface, not a class
    • You don't need to specify <P extends Comparable<P>>
    • It might make more sense to move the addValHelper code into the Node class itself
    • It might make sense for Node to implement Comparable.

    This way, your code feels a lot more idiomatic and you don't expose fields of Node to BST.

    public class BST<T implements Comparable<T>> {
        private final Node<T> root;
    
        /** Presumably this is run when a value is added.. */
        private void addValueHelper(Node rootNode, Node newNode) {
            rootNode.attachChild(newNode);
        }
    
        public static class Node implements Comparable<T> {
            private final T val;
            private Node left;
            private Node right;
    
            public Node(T val) {
                this.val = val;
            }
    
            public int compareTo(Node other) {
                return this.val.compareTo(other.val);
            }
    
            /**
             * Takes the given node and compares it with the current node.
             * If the current node is greater than the given node, the given node is placed to the left.
             * Otherwise it is placed to the right.
             */
            protected void attachChild(Node newNode) {
                if (this.compareTo(newNode) == 1) {
                    if (this.left == null) {
                        this.left = newNode;
                        return;
                    }
                    this.left.attachChild(newNode);
                    return;
                } 
    
                if (this.right == null) {
                    this.right = newNode;
                    return;
                }
    
                this.right.attachChild(newNode);
            }
        }
    }