2014-10-12 3 views
1

고가, 저는 주로 C & C++에 익숙하지만 최근에 Java에서 손을 썼습니다.Java에서 객체 비교 문제 (Context is RB Tree)

제 문제는 라인 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; 
} 

답변

2

Java의 모든 객체는 reference type을 나타냅니다. 일반적으로 참조는 객체 또는 배열이 저장되는 메모리 주소입니다. 그러나 Java 참조는 불투명하고 어떤 방식으로도 조작 할 수 없으므로 이는 구현 세부 사항입니다. 따라서 Java에는 C++과 같은 포인터가 실제로 없지만 객체에 대한 참조가 있습니다.

제안한 해결 방법을 사용하면 가장 쉽고 간단한 방법으로 문제를 해결할 수 있습니다. 그러나 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)가 제대로 작동하지 않습니다.

우리는 값이 동일하게 두 개의 객체를 고려하는 것이 같아야합니다 결정. 귀하의 경우에는, 당신은 제대로 hashCode 구현이 필요한 용기에 Node 목적을두고 있지 않기 때문에, 당신은 단지 hashCode없이 equals() 메소드를 오버라이드 (override) 할 수 있지만 가능한 결과를 알고 있어야합니다.Node 클래스 내부의 equals() 방법은 자신의 키를 기준으로 노드를 비교할 수와 같은 보일 것이다 :

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

사용의 장점 : 그럼 당신은 당신의 코드에서 다음과 같은 문장을 사용할 수 있습니다

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 
    } 
    */ 
} 

equals() 구현은 많은 특정 방식으로 객체 평등을 정의 할 수 있으므로 매우 유연한 솔루션입니다.

Here is a good stackoverflow thread on this

Here is another useful read