1

高,我最熟悉 C 和 C++,但我最近一直在尝试使用 java。

我的问题是这条线if (parent.leftChild == temp)永远不是真的。虽然parent.leftChild.Key = temp.key(其余内容相同),但我的印象是,问题在于 Eclipse 调试器中的 parent.leftChild 的 ID = ...5792,而 temp 的 ID 为 ...3632。

我希望有人可以进一步解释。我的代码的解决方法总是可以将 if 语句更改为if (parent.leftChild.key = temp.key),但不应该parent.left == temp是有效的?

class Node{
int key;
char color;

Node leftChild;
Node rightChild;
Node parent;
//...constructors..//
}

private Node GetParent(Node node){
    if(node != null)
        return node.parent;
    else
        return null;
}

private void RemoveNodeFromTree(Node myNode){
    Node temp  = new Node(myNode);

    //traverse
    if(temp.leftChild!= null){
        temp = temp.leftChild;
        while(temp.rightChild!= null)
            temp = temp.rightChild;

        myNode.key = temp.key;
    }
    else if(temp.rightChild != null)
        myNode.key = temp.rightChild.key;

    Node parent = GetParent(temp);
    Node childL = temp.leftChild;
    Node childR = temp.rightChild;

    //have parent point to the proper new node.
    //parent points to left if it exists, then it tries right. 
    //if both are null, point to right anyway
    if(parent !=null ){
        //replace temp with it's left child
        if(childL!= null){
            if (parent.leftChild == temp)
                parent.leftChild = childL;
            else
                parent.rightChild = childL;

            childL.parent = parent;

            childL.color = 'B';
            if(childL.color == 'B' && temp.color == 'B')
                DoubleBlackRestructure(childL, parent);
        }
        else //replace temp with it's right child
        {
            if (parent.leftChild == temp)
                parent.leftChild = childR;
            else
                parent.rightChild = childR;

            if(childR!= null)
                childR.parent = parent;

            if((childR == null || childR.color == 'B') && temp.color == 'B')
            {
                if(childR != null)
                    childR.color = 'B';
                DoubleBlackRestructure(childR, parent);
            }
            else if (childR != null)
                childR.color = 'B';
        }
    }
    else
        myNode = null;
    temp = null;
}
4

1 回答 1

2

Java 中的每个对象都代表一个reference type. 通常,引用是存储对象或数组的内存地址。但是,由于 Java 引用是不透明的并且不能以任何方式进行操作,因此这是一个实现细节。因此,Java 并没有像 C++ 这样的指针,但它具有对对象的引用。

至于您的问题,使用您建议的解决方法应该是解决问题的最简单和最简单的方法。但是,如果您想比较一般 Java 中的对象,请按照以下方法进行。

Java 有两种对象相等性:

对象引用相等:当两个对象引用指向同一个对象时。

if (obj1 == obj2) {
    // The two object references point to the same object
}

对象值相等:当两个单独的对象碰巧具有相同的值/状态时。

if(obj1.equals(obj2)) {
   // two object references contain "equal" objects
}

“相等”用引号引起来的原因是因为我们可以说两个对象何时完全相等。

为了能够对同一类的两个 Java 对象进行值比较,该boolean equals(Object obj)方法必须被该类覆盖和实现。

请注意,相等的对象必须具有相等的哈希码。因此,在重写equals方法时,我们也必须重写hashCode方法。不这样做就违反了该hashCode方法的一般约定,并且任何使用哈希码的类HashMap都将无法正常运行。

我们决定哪些值必须相等才能认为两个对象相等。在您的情况下,您可以只覆盖该equals()方法而不使用,hashCode因为您没有将Node对象放入任何需要正确实现的容器中,hashCode但您应该注意可能的后果。类中的equals()方法Node可以根据节点的键比较节点,看起来像:

class Node {
    int key;
    char color;

    Node leftChild;
    Node rightChild;
    Node parent;

    //...constructors..//

    boolean equals(Object obj) {
        //null instanceof Object will always return false
        if (!(obj instanceof Node)) {
            return false;
        }
        // each object is obviously equal to itself
        if (obj == this) {
            return true;
        }
        return  this.key == ((Node) obj).key;
    }

    /* This is a simple example of how to override the hashCode as well.
    public int hashCode() {
        // some code to represent each node uniquely
        // i just assume each node has a unique key
        return this.key
    }
    */
}

然后,您可以在代码中使用以下语句:

if (parent.leftChild.key.equals(temp.key))

使用equals()实现的优点是您可以通过多种特定方式定义对象相等,因此它是一个非常灵活的解决方案。

Here is a good stackoverflow thread on this

Here is another useful read

于 2014-10-12T01:16:41.503 回答