public class StackWithLinkedList<P> {
private Node top = null;
public StackWithLinkedList(){}
public void push(P val){
Node newNode = new Node(val);
if (this.top != null) {
newNode.nextLink = top;
}
this.top = newNode;
}
public void traverse(){
Node currentNode = this.top;
while(currentNode != null){
System.out.println(currentNode.val);
currentNode = currentNode.nextLink;
}
}
private class Node{
Node nextLink;
P val;
public Node(P val){
this.val = val;
}
}
}
Look at this code in the traverse(),
Node currentNode = this.top;
here an object of type Node is created that points to the already existing this.top node object.
So it means, two references pointing to the same object in memory isn't it?
But when I use the traverse() method, both the object works independently as the currentNode gets to Null after traversing but the this.top remains unchanged, holding all the nodes that have been pushed.
I tried debugging and i saw this.top has the same memory address as the currentNode.
In the end,
I am not able to figure out why is it?
CodePudding user response:
You are conflating "object" and "reference". For example in the sentence
For example here:
Look at this code in the traverse(),
Node currentNode = this.top;
here an object of type Node is created that points to the already existing this.top node object.
No object of type Node
is created here (there is no new
, that's how you know).
What is defined here is a (local) variable of type Node
. And the reference that is stored in this.top
is also assigned to currentNode
.
So it means, two references pointing to the same object in memory isn't it?
Yes, this part is again correct.
Think of a reference like a sheet of paper. The paper can be empty (i.e. the reference is null
) or it can have some address written on it (i.e. it points to some object).
Now currentNode
is a piece of paper that happen to have the same address written on it that this.top
also has written on it (it's a tiny bit more complicated, because this
is a piece of paper written on it and if you look at that address then you'll find some other piece of paper labelled top
that has some address written on it, but that doesn't fundamentally change how this works).
At some point later in the code currentNode
gets reassigned (i.e. the content of the piece of paper gets changed). First to a different address (i.e. the address scribbled out and replaced with another one) and then eventually with null
(i.e. you scribble out the content and leave it "blank").
But just because you wrote on that piece of paper doesn't mean that the other piece of paper (found via this.top
) has changed. There is no reason for to it change: they are two independent pieces of paper that at one point happen to have had the same stuff written on them.
Or put differently: assigning a new value to currentNode
has absolutely no effect on the object previously referenced by currentNode
.
If you had done currentNode.nextLink = null
instead of (basically) currentNode = null
then that would be different:
currentNode = null
means "remove the address written on the piece of paper labelledcurrentNode
.currentNode.nextLink = null
means "go to the address written on the piece of paper labelledcurrentNode
, there find a piece of paper labellednextLink
and remove the address written on it.
The first one just changes the reference currentNode
and the second one actually changes the object pointed to by currentNode
.
Edit: it seems your confusion stems from the debugging view where it says currentNode = {StackWithLinkedList$Node@801}
. You seem to interpret this as "currentNode
is the object {StackWithLinkedList$Node@801}
", but that's not what it means.
currentNode
is never an object. It can't be. Java variables/fields can't hold objects. So what that display really means is: currentNode
currently references the object represented as {StackWithLinkedList$Node@801}
.