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.
Related
My question is clear. Is a copy constructor make a deep copy? or a shallow copy?
Here is the situation I faced:
I'm making a node editor application. I've a abstract Node class. In that, I've abstract method called Create(). Also I overrode that method in all sub classes in this way,
public Node Create(){
TestClass theTest = new TestClass();
theTest.Name = "Test Node";
theTest.Title = "Default Node";
theTest.setSize(new Point2D.Float(250,200));
System.out.print(theTest.getClass());
return theTest;
}
I thought this should make a deep copy. Since that didn't work, I tried this also.
public Node Create(Point2D location) {
TestClass theTest = null;
try {
theTest = this.getClass().newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
if (theTest != null) {
theTest.Name = "The Node";
theTest.Title = "Defaul Node";
theTest.setSize((new Point2D.Float(250,200)));
theTest.Location = location;
}
return theTest;
}
Then all the subclass types are added into a list and a popup menu is created with subclasses. User can click it and add a new node. This is the code to add a node. This method is called by a MouseEvent of the JMenuItem.
private void addNode(Node node){
Node newNode = node.Create(locationPersistence);
nodes.add(newNode);
}
But no luck. It seems to create a shallow copy instead of a deep copy. When I add the first node, it appears fine. But when adding a second node of same type, first node disappears from there and reappear at the new Location. Does this mean that this is making a shallow copy. If so, how to achieve a deep copy?
First, there is no such thing as copy constructor in Java by default. There is a Cloneable interface and clone() method. But that method by default will make shallow copy.
Your code sets link to the same Point2D object references in property location for both objects. You need to create new instance of Point2D object and use it in new object.
Java avoids deep copying.
For the immutable String class this is no problem, as Strings may be shared.
For the old mutable java awt Point2D.Float class one indeed has a problem. Substituting it for an immutable class would probably be better - than a deep copying.
The javafx.geometry.Point2D is immutable.
For mutable arrays there is a problem. Even a final array can have its elements changed from outside. Here the advise would be to use collections instead.
private final List<Point2D> points = new ArrayList<>();
public List<Point2D> getPoints() {
return Collections.unmodifiableList<>(points);
}
Use the java convention of field and method names starting with a small letter.
Java is quite rigorous with respect to that.
C/C++ partly need deep copying for keeping objects on the local stack.
Java removed the need somewhat for copy constructors, but historically failed for String: String has a senseless copy constructor, probably instigated by intern() and having an internal char array.
A copy constructor is when your class contains a constructor that accepts an instance of itself as parameter. The parameter is used to create a new instance of the class that has the exact same values for its fields as the instance class that was provided as parameter.
Your Node class will have to have a constructor like this:
public class Node {
public Node(Node n) {
//copy all fields in Node n here
//eg this.a = n.a
//this.b = n.b etc
}
}
Then when you inherit from Node, you need to call this parent method in the child class constructor as well:
public class TestClass extends Node {
public TestClass(TestClass t) {
super(t);
//copy any additional fields that is only present in TestClass here
}
}
Now, difference between shallow and deep copy.
Shallow copy is when a reference is set equal to another reference.
Eg:
Point2D a = new Point2D(50, 50);
Point2D b = a;
When you change the value of one of a's members, b will also be affected. The reason is that both a and b is a reference to the same object.
a.x = 100;
System.out.println(b.x == 100); //prints true
Now deep copy is if both a and b refers to their own instances. This can be done as follows:
Point2D a = new Point2D(50, 50);
Point2D b = new Point2D();
b.x = a.x
b.y = a.y
If I now type:
a.x = 100
then b.x will not change to this same value, but keep the previous value that was originally store in a, in this case 50.
System.out.println(b.x == 100); //prints false
System.out.println(b.x == 50); //prints true
If you want to have deep copy in your constructor, then you need to ensure that all members of the class that are references to mutable classes, refer to their own instances
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:
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.
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.
class Nodetype
{
int info;
Nodetype next;
Nodetype(int i)
{
info=i;
next=null;
}
}
My textbook has this code to create Linked List dynamically.
The question is, when the programs is executed line-by line, it defines variable 'info' as type 'int' & then variable 'next' as Nodetype.
What is actually happening here?
does it mean that variable 'next' will contain -
Constructor 'Nodetype'
int info
Nodetype "next" where "next" will again have all 1,2,3 & then 3 will again have 1,2,3...and so on....till infinity?
I'm really irritated because I'm unable to understand how it works, can someone easily explain this?
Your code follows very well the definition of list: a list is null or an element followed by a list.
The "element", in your case, is defined by an int value, and the "followed by" part is the next variable; in Java variables (when they are not literals, as int values are) are actually pointers, so while they are not initialized they don't store any valid value and they don't point to any memory area (i.e. their value is null), so while the next variable is kept as-is your element is not followed by any other. To dynamically add elements to your list you need a pointer to the last element you added, otherwise you would not be able to find them again:
int i = 0;
Nodetype head = new Nodetype(i++);
Nodetype last = new Nodetype(i++);
head.next = last;
while (i<5) {
Nodetype temp = new Nodetype(i++);
last.next = temp;
last = temp;
}
while(head) {
System.out.println(head.info);
head = head.next;
}
Notice how, with the last few lines, you lose the head pointer and you have no way to get back the starting point of your list.. Keep that in mind when working with lists ;)
At first variable next doesn't point to any object(it points to null). At some time you will make it point to another node with next = new NodeType(number). The idea is that you use composition - you have one instance of class which has a reference to another instance. It is like nodeA points to nodeB, nodeB points to nodeC. Here you have three instances and the first instance has a reference to the second instance and the second instance has a reference to the third instance. The third instance is the last one and its next instance points to null.
the field next is a reference to an object of type Nodetype. at first it will point to nothing - since it is instantiated to null. when you assign a value to it, it will point to that value only, nothing will continue infinitely unless you create a cycle within the list.
You created class NodeType and inside of the class you defined object of that class. So that object (in your example next) will have int info variable NodeType next object and constructor.
It will contain Null, as the variable is not initialized to any value.
Nodetype is your class that defines the data a node instance will contain as well as the reference to the next node in the linked list. That reference to the next node will be an object of type Nodetype. Nothing too difficult here, this is the classic implementation of a Linked List.
You might want to check out this great linked list resource from Stanford.
The way this works is that the list is made up of single elements, each of which only has a pointer to the one that comes after it:
Nodetype next;
The information each element within the list actually holds is this:
int info;
You can think of a list like a "chain": it's not really a single object, but a compound object of a number of links. From each link, you can only see the next link (or, in case of linked lists that have references in both directions: the next and the previous link), so in order to have all elements available, you will have to keep the reference to the first element in the "chain".
Note: List objects are single objects that have a reference to the first link of the "chain".
next is a reference to another Nodetype instance. If next == null it means the current element is the last one in the list.
Let's see an example:
Nodetype node = new Nodetype(0); // i = 0, next = null
Nodetype anotherNode = new Nodetype(1); // i = 1, next = null
node.next = anotherNode; // now the first node has a ref to the second
#include<stdio.h>
#include<stdlib.h>
void print_list(int *arr,int *size,int *capacity)
{
printf("capacity = %d; size = %d; elements = ",*capacity,*size);
for(int i=0;i<(*size);i++){
printf("%d ",arr[i]);
}
printf("\n");
}
int * push_back(int *arr,int data,int *size,int *capacity)
{
int *b;
if(*size == *capacity){
*capacity = 2*(*capacity);
b = (int *)malloc(sizeof(int)*(*capacity));
for(int i=0;i<(*size);i++){
b[i]= arr[i];
}
b[*size]=data;
*size=*size+1;
print_list(b,size,capacity);
return b;
}
arr[*size]=data;
*size=*size+1;
print_list(arr,size,capacity);
return arr;
}
int main()
{
int size=0;
int n;
int x;
int *arr;
arr = (int *) malloc(sizeof(int));
int capacity=1;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&x);
arr=push_back(arr,x,&size,&capacity);
}
}
its working.