Reference, Object, LinkedList - java

So I am building a LinkedList from scratch. Though the code works, I am confused on two things.
When you write (public node root) you are creating a reference to the object? In other words is this a pointer? If yes, in the method add() I check to see if root equals to null for the first iteration, which it is and the code creates a instance of that class.
My problem comes in method Find(). When root is null, and I set temp1=root, isn't temp1 also going to be null since root is null? Or temp1 is pointing to root and root is pointing to null? How different are these?
Edit: if temp1 is null then why is method find() working?
public class LinkedList {
public Node root;
public void add(int data) {
if(root == null) {
root = new Node(data);
}
else {
Node temp1 = root;
Node temp = new Node(data);
while(temp1.getNext() != null) {
temp1 = temp1.getNext();
}
temp1.setNext(temp);
}
}
public boolean Find(int data) {
Node temp1 = root;
while(temp1 != null) {
if(temp1.getData() == data) {
return true;
}
temp1 = temp1.getNext();
}
return false;
}
}

When you write (public node root) you are creating a reference to the object?
Yes. You're declaring an object reference of type Node. Since you are not initializing this, the reference value is null. Java references are like pointers in other languages, although there are some key differences. Like a pointer, the value of an object reference will be a memory address that contains your object. Unlike some other languages, you can't do pointer arithmetic with Java references.
The Java Language Specification has this to say about the issue:
The reference values (often just references) are pointers to these
objects, and a special null reference, which refers to no object.
I was initially making a more syntactic argument, but after going back to the JLS, I agree that references are pointers, even though C-Style pointer operations aren't supported in Java.
When root is null, and I set temp1=root, isn't temp1 also going to be null since root is null?
Yes, temp will be assigned the value of root. That is, it will reference the same Node instance that root is currently referencing. If root is null when this call is made, then temp1 will also be null.
In your code, you could (probably should) initialize your root Node in a constructor like so. This will initialize your root node each time you call new LinkedList() in some other method. Note that I made a couple other minor changes to make this class conform more closely to :
public class LinkedList {
// made this private
// be sure to add get/set methods to access/change this value
// if needed outside this class
private Node root;
// default (no-arg) constructor
public LinkedList() {
root = new Node();
}
public void add(int data) {
Node temp1 = root;
Node temp = new Node(data);
while(temp1.getNext() != null) {
temp1 = temp1.getNext();
}
temp1.setNext(temp);
}
public boolean find(int data) {
Node temp1 = root;
while(temp1 != null) {
if(temp1.getData() == data) {
return true;
}
temp1 = temp1.getNext();
}
return false;
}
}

Any object-valued variable in Java is actually a reference to the actual object that is stored on the heap.
In your Find method, you're assigning the reference to root to temp1, you now essentially have 2 references to the same Node object.
If you call Find before calling add, root (and temp1 since they refer to the same object) are null so this function will always return false.
Only after calling add, where a reference to a Node object will be assigned to root, will it be possible for it to return true.

Related

Java, what is happening internally when you do object = object?

I am implementing singly linked list in Java, and I have a problem.
In addition and removal of nodes, many people use temporary node like this:
public Object removeFirst() {
Node temp = head;
head = temp.next;
Object returnData = temp.data;
temp = null;
size--;
return returnData;
}
Why is this temp node necessary? At first glance, I think all I have to do in order to remove first element is to change second element into head node.
So my question is that in java, what does object= object mean? Do 2 objects become exactly same inheriting every fields and methods?
temp is not needed. It is used to obtain the data of the removed Node after the head variable is no longer referencing that Node, but that can be done without it:
public Object removeFirst()
{
Object returnData = head.data;
head = head.next;
size--;
return returnData;
}
what does object= object mean?
A class provides the blueprint for objects; you create an object from a class.
The new operator returns a reference to the object it created. This reference is usually assigned to a variable of the appropriate type
Assume that you have create new object head
When you copy one object to another object, then second reference is created to the object.
Node temp = head;
If you make second object (reference) as null,this object is still accessible with first reference (head).
Do 2 objects become exactly same inheriting every fields and methods?
Yes since only reference is different but object is same.
You can find more details in oracle documentation page
When you did not create object ( instantiate class):
When you create an object with new operator:
When you assign object to another object:

Can I define an object as equal to another one in Java?

In Java programs, is it right to set an object equal to another one? To be more specific, I'm studying binary trees and I noticed in the following code:
public Node find(int key)
{
Node current = root;
while(current.iData != key)
{
if(key < current.iData)
{
current = current.leftChild;
} else {
//...
}
}
}
that both Node current = root; and current - current.leftChild; are setting an object equal to another one. Is this right?
setting an object equal to another one. Is this right?
No, that's not right.
What's actually happening is, you're changing the reference of one variable to another object.
So:
Node current = root; // "current" will point at the same object as `root`.
and
current = current.leftChild; // "current" will point at the same object as `leftChild`.
note -
When assigning primitive types with = is a completely different behaviour when assigning reference types with =.
First of all, you need to need a basic concept in Java: Java does manipulate objects by reference, and all object variables are references.
So when you have Object o1 and Object o2, in fact o1 and o2 are just references to memory spaces that hold the object not the object itself.
When you have o1 == o2 , you are comparing the two references not the objects themselves but if you want to compare them you need to override the equals() method.
Now, let's talk about your case:
Node current = root; this means that current and root are referring to the same object (the same location in memory). So there is only one object and two references.

Is there a difference in functionality when you use an intermediate variable during assignment?

I'm having trouble understanding what makes method A different from method B.
public class ListNode {
public String data;
public ListNode next;
public ListNode(String data, ListNode next) {
this.data = data;
this.next = next;
}
}
public void A(ListNode list, String name) {
ListNode asdf = new ListNode("hello", list);
list = asdf;
}
public void B(ListNode list, String name) {
list = new ListNode("hello", list);
}
No difference (functionally speaking).
Note that re-binding a method parameter is confusing because parameters in Java are passed by value, so when the method ends, list will be the same value as before the method call, no matter if you re-bind inside the method. This means your newly created ListNode object will have no strong reference and will be eventually garbage-collected.
For example:
final ListNode a = new ListNode("pre-call", list);
A(a, "Some name");
System.out.println(a.data); // Here it will print "pre-call" and not "hello"
Also it is usually considered a bad practice to re-bind parameters (kind of same as reusing variables). To avoid such mistakes I always declare method parameters as final.
The only difference is the readability of the two methods. Rest both the methods are doing the same thing
In method A the first reference is asdf for newly created ListNode object. this ' list = asdf' makes list as another reference to same ListNode object. Thus in method A there are two references for same object.
And the method B also does the same thing ie creates a new ListNode but this time using list as only reference.
Both methods achieve same thing but method A creates two references and assigns object to list indirectly while B on other hand directly uses list as a reference.

What does "this" refer to exactly in this code?

public CharList(CharList l)
{
// Whatever method your CharList provides to get the
// first node in the list goes here
CharNode pt = l.head();
// create a new head node for *this* list
CharNode newNode = new CharNode();
this.head = newNode;
// Go through old list, copy data, create new nodes
// for this list.
while(pt != null)
{
newNode.setCharacter(pt.getCharacter());
pt = pt.getNext();
if (pt != null)
{
newNode.setNext(new CharNode());
newNode = newNode.getNext();
}
}
}
I thought that this is used to refer to the Object A as in "A.addElement(car);", but in this case I don't know what this refers to... And I don't see the point in doing: this.head = newNode; since this.head is never used again.
this refers to the current instance of CharList, and this.head refers to the instance field head. You can discard this keyword to access instance fields if there are no local variables with the same name.
The docs explain what this is:
Within an instance method or a constructor, this is a reference to the current object — the object whose method or constructor is being called. You can refer to any member of the current object from within an instance method or a constructor by using this.
The keyword this refers to the current instance of CharList. It is useful for referring to variables that may share the same at class level, otherwise it can be omitted.
Here, no local variable head does not appear in the constructor of CharList, so can be written as:
head = newNode;
this.head is never used again.
Since head is a member variable of the class, the value set in the constructor will be used in other methods of the class.
Possible duplicate of What is the meaning of "this" in Java?, but anyway:
It's a reference to the specific instance of the object you're working with. So, if I have (going to write this in C#, sorry):
public class MyObject
{
public MyObject(string AString)
{
MyString = AString;
}
private string MyString;
public string WhatsMyStringCalled()
{
return this.MyString;
}
}
If I were to construct an instance of MyObject, I would expect WhatsMyStringCalled to return the MyString property associated with that particular instance.

Pass by value - tree not deleted [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java, pass-by-value, reference variables
I am a bit confused on how exactly JAVA pass by value works with object. For e.g. if I pass a object as a parameter to the method. I understand that its address is passed as value. Ok, is a duplicate of the object is kept at the original place form where the object is passed, because if I create a new reference to the object in the called API and change something in it, it doesn't get reflected in my caller API.
Below is a typical piece of code where I try to delete a tree but it's still there.
public class DeleteTree {
public static void main(String[] args) {
Node root = new Node(5);
for(int i = 0 ; i < 10 ; i++){
if(i == 5) continue;
root.insertNode(i);
}
deleteTreeNonRecursive(root);
System.out.println(root.key);
}
public static void deleteTreeNonRecursive(Node root){
Queue<Node> q = new LinkedList<Node>();
q.add(root);
while(!q.isEmpty()){
Node temp = q.poll();
if(temp.leftChild != null)q.add(temp.leftChild);
if(temp.rightChild != null)q.add(temp.rightChild);
temp = null;
}
}
Expected O/P: nullpointer exception.
Actual O/P: 5.
In Java you always pass by value the reference to the object (which is itself allocated onto the heap). No duplication occurs because you are just passing pointers around.
In your example you are just setting temp = null but this indeed does nothing just because temp is a pointer to a Node but it's a variable local to the function, when you set it to null the original object is not touched at all just because you are just modifying the value of the reference without modifying the referenced object.
To delete the tree this is the only thing you need:
Node root = new Node(5);
for(int i = 0 ; i < 10 ; i++){
if(i == 5) continue;
root.insertNode(i);
}
root = null;
Java always uses pass by value. It's the value of the reference that is passed when it comes to object references. When you pass an object reference, it's a copy of the reference value which is passed. Using that, you can always access the object and change its properties (wherever applicable), but assigning that reference to another object or null has no consequences to the original reference in the calling method obviously.

Categories