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

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

Posted by: admin December 28, 2021 Leave a comment

Questions:

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?

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

###

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)

###

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.