Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java : setting object to null within a method has no effect (Reusing code)

I am trying to write a method to delete a Node from a Binary Search Tree. Here is my method to delete a node.

public void delete(int deletionNodeValue) {
    Node<Integer> nodeToBeDeleted = getNode(deletionNodeValue);
    if(nodeToBeDeleted == null) return; // No node with such value exists throw an error
    if(isLeafNode(nodeToBeDeleted)) {
        nodeToBeDeleted = null;
    } else if (nodeToBeDeleted.getNumChildren() == 1) {
        bypassNode(nodeToBeDeleted);
    }else {
        replace(nodeToBeDeleted, getSuccessor(nodeToBeDeleted.getValue()));
    }
}

I checked this method on a leaf node, though after debugging I discovered that the execution of nodeToBeSelected=null takes place, the node isn't actually deleted. As I can still search for the deleted value and program still manages to fetch it.

tree.add(5);
tree.delete(5);
System.out.println(tree.getNode(5).getValue()); // Output : 5, should've been deleted

Here is my getNode() method

public Node<Integer> getNode(int searchValue) {
    Node<Integer> currentNode = root;
    while(currentNode != null) {
        int currentNodeValue = currentNode.getValue();
        if(searchValue == currentNodeValue)
            return currentNode;
        else if(searchValue < currentNodeValue)
            currentNode = currentNode.getLeftChild();
        else
            currentNode = currentNode.getRightChild();
    }

    // if no node with given value is found
    return null;
}

Is getNode() method returning the found node by value? How can I make it return reference and directly manipulate the found node?

like image 404
Nash Vail Avatar asked May 31 '15 16:05

Nash Vail


People also ask

Can you set an object to null in Java?

In Java, a null value can be assigned to an object reference of any type to indicate that it points to nothing. The compiler assigns null to any uninitialized static and instance members of reference type.

What does setting an object to null do?

If the reference is an instance variable, then setting it to null makes the object available for GC as long as there are no other references to it. However, if you set an instance variable to null, no other method in the class will be able to access that object using that variable.

How do you pass a null object?

Passing a null value to any Corticon Server using JSON payloads is accomplished by either: Omitting the JSON attribute inside the JSON object. Including the attribute name in the JSON Object with a value of JSONObject.


3 Answers

You have to delete the node from the tree and not locally in your program.

Node<Integer> nodeToBeDeleted = getNode(deletionNodeValue);

gives you a copy of the Node in the tree.

nodeToBeDeleted = null;

sets this copy to null. The connection to the tree is not deleted because it is part of the node object. To delete the connection you would have to write another method to delete a Node and this should contain something like

parent.leftNode = null; // if nodeToBeDeleted == leftNode
parent.rightNode = null; // if nodeToBeDeleted == rightNode
like image 181
CoronA Avatar answered Sep 27 '22 22:09

CoronA


When you say nodeToBeDeleted = null; inside the delete method, you are not really causing the Node returned by the getNode method to start pointing to a null.

Java is always pass-by-value. This means that you can't make a reference passed to a method point to a new memory location inside the method. Similarly, you can't make a reference returned by a method call point to a new memory location inside another method. (Even if the location is, well.. a null).

As per the above explanation, it's almost impossible to use the getNode method to get the Node that you wan't to delete and then make this node point to a null in some other method. A quick solution would be to duplicate the code in the getNode method inside the delete method as well. You should add a setLeftChild and setRightChild method in Node (as opposed to making leftChild and rightChild public as proposed by others). You can then set it to null as follows :

nodeToBeDeleted.setLeftChild(null)

like image 29
Chetan Kinger Avatar answered Sep 27 '22 22:09

Chetan Kinger


When you set nodeToBeDeleted to null, you only set the value of the local variable that holds the reference to the actual object. The actual object is not deleted in any way.

With the code you've shown here, to delete the node, you should find its parent and set the reference to this node (leftChild or rightChild) to null. This will ensure that the object is not referenced by its parent, probably no longer visible by any reference, and consequently eligible for garbage collection.

like image 38
Sergei Avatar answered Sep 27 '22 23:09

Sergei