Java, How does add to an arraylist work - java

I am trying to get more familiar with java recently. A question occurred to me which I couldn't find the answer online. I am wondering when java adds an element to an arraylist, is the added element associated with a variable name? For example in the following code:
E obj1 = new E();
E obj2 = new E();
List myList = new ArrayList<E>();
myList.add(obj1);
obj1 = obj2;
After the new assignment to obj1 will the value exist in myList change or not?

No, when adding an object to a List, the reference is copied and therefore when you assign obj1 with new value, the list will contain the old one.

In Java, it's "all about references".
A new instance is created only when you use new.
In all other assignments, such as obj1 = obj2, you are only changing the reference to the actual instance.
The only exception for this rule are assignments that involve primitive types such as char and int.
When you do myList.add(obj1), you add an entry in myList, which contains a reference to the instance referenced by obj1.
At this point, this instance has two references (one by obj1, and one by the entry in myList).
When yo do obj1 = obj2, the same instance remains with only one reference (in myList).
When the number of references to an instance becomes 0, it is deleted by the garbage collector.

No ,in your case obj1 will not change in ArrayList because you already added obj1 to ArrayList before changing the obj1 to obj2.

ArrayList is as same as Array excepts its dynamic expending features.
ArrayList is container, internally it is having a array inside it, which stores object reference.
myList.add(obj1);
This will store the reference value not reference to list.
obj1 = obj2;
This will does not effect any change in list.

After obj1 = obj2;, first instance of object E is destroyed because both of obj1 and obj2 are pointing to the same instance (the one from line 2 E obj2 = new E();).

Java is always pass-by-value. That means that the original variable before you pass it is never changed by anything done inside methods/objects/etc that you call.
However the thing that confuses people here is that when you pass an object you actually pass a reference to that object by value.
Which is what is giving you the behavior here.
You have passed a reference to the object into the list. The reference has been passed by value. That means it has been copied, and you can change the reference (but not the thing it points to) as much as you like and the method you called will not see any change.

Before this question is answered the first thing to remember is that whenever you come across object is assigned to another object , you need to consider that reference is like remote control to the object. but in case object is assigned to another object , your reference(remote control) no longer controls your obj.
lets go line by line to see whats happening:
E obj1 = new E();
// the obj1 is created and holds reference to a memory location let's say 1a2s3d
E obj2 = new E();
// the obj2 is created and holds reference to say 5g5g5g5 .
List myList = new ArrayList<E>();
// empty list created acception elements of type E
myList.add(obj1);
//myList now points to reference 1a2s3d by addition of obj1 .
obj1 = obj2
//obj1 and obj2 now point to same reference .. 5g5g5g5
and myList still points to reference 1a2s3d because it points to reference not obj1.
So its value will not change.
Also any new changes to elements of obj1 or obj2 like setting value of any field in obj1 of class
E will change value of that field in obj2 also . thus the code is (obj1==obj2) ?? will return true.

obj1 contains a reference to an instance of the class E. When you 'add' the object to the list you are adding the reference to it so the list knows who is the new buddie.
When making obj1 = obj2 you are changing the value of obj1, not the instance itself, so that both variables point to the same instance of E.
Object variables are just a reference, so you are just changing the reference. Therefore, the instance you created with
E obj1 = new E();
is still alive and not changed at all.
By making an assignment of object variables you will never ever change the object itself but the reference.
Note: if an instance remains without being pointed by some variable the garbage collector of java will delete it. This is not the case as the instance is now pointed by the list.

Related

Why can you change field variables with an enhanced for loop but you cannot initialiaze objects?

I recently learned that you cannot initialize objects using an enhanced for loop in Java because of the way an enhanced for loop works by creating a 'dummy' object from the object and then performing whatever the code states using the dummy object
But this prompted me to attempt to change field variables inside objects using an enhanced for loop and surprisingly the code changed the field variables in the objects. Can anyone please explain to me how this works because to my understanding no change should occur to the objects for the same reason you can't initialize objects using the enhanced for loop. Clearly I have exposed a gap in my understanding here so can anyone help me out
In java the objects you see are not objects but in fact object references.
An object reference is just an reference to the object in RAM.
For example.
Person p1;
Person p2;
p1 = new Person(); // p1 now has an reference to an Person object
p2 = p1; // Now p2 and p1 point to the same object
Now, if we made a change to the p2's object, that change would be reflected to p1's object because they refer to the same object.
For example.
p2.setHeight(50);
p1.setHeight(90);
System.out.println(p2.getHeight());
The code snippet above would print out 90, not 50. Because first the object's height was set to 50, but then the objects height was set to 90(using some other object reference).
Going back to your question.
for(Person p : peopleArray)
{
// more code
}
In every cycle of the for loop, an object reference p is created and refers to the same object that an object reference in peopleArray refers to.
In an enhanced for loop you are allowed to modify objects, but you are not allowed to change the data structure you are iterating through. This means you can change the fields of objects but you can't add or remove items from the data structure. Nor are you allowed set a whole new object to one that is already in the list. If you modify the list, there will be a ConcurrentModificationException thrown.
Are you asking about this:
for (Animal a: animals)
{
a=new Dog(); // wrong
}
If so, think of a as defined in this case as final Animal a. Therefore the reference variable is immutable. But the member fields of the objects (if any) are not necessarily immutable.
for (Animal a: animals)
{
a.Name = "Jack"; //valid, if Name is a mutable member field.
}

Reference to object?

I have an ArrayList of objects.
I "retrieve" one of those objects with something like:
MyObjectClass myObject = myArrayList.get(34);
If I subsequently make modifications to myObject, such as:
myObject.someMember = 97;
is it just doing it to a local COPY of the object or the actual object within the array list? That is, is the myObject variable a copy or is it a REFERENCE to the object within the array list?
In Java, a name referring to an object always has reference semantics. Container get functions idiomatically return the same reference that the container holds.
If a function wants to return a local copy, or you want a local copy, this is done using new.
MyObjectClass myObject = new MyObjectClass( myArrayList.get(34) );
is it just doing it to a local COPY of the object or the actual object
within the array list? That is, is the myObject variable a copy or
is it a REFERENCE to the object within the array list?
Yes it will make changes in the object state which is in ArrayList
Neither. Both myObject, and the item in the arraylist, are references to the object which is stored elsewhere.
The ArrayList does not hold the object, only a reference to the object (just like your reference to the object). Objects are never stored inside other objects in Java, although sometimes it is convenient to think of them that way.

One object in a 2 collections (Reference)

I'm curious about the object reference in java let's say we have a Person object
Person object = new Person("Joe");
I put it in an ArrayList<Person>
ArrayList<Person> person_collection = new ArrayList<Person>();
person_collection.add(object);
I create a new collection of Person again, then copy the items of person_collection
ArrayList<Person> collection = new ArrayList<Person>(person_collection);
If I get the item from collection
Person p = collection.get(i);
Is p has a reference to person_collection ??
In this case, p contains in the initialization step at least all the elements of person_collection.
So when you directly iterate over this newly created collection, you will get the same pointed Person elements that the ones contains into the initial collection.
By the way, as Java never use the pass-by-reference but always the pass-by-value method, references themselves are not the same but that does not prevent them to point to the really same objects.
Yes, the Person "object" variable reference will be returned back in Person "p" variable .
person_collection and collection will be referencing 2 different collections containing the object pointed p.

Adding to a Vector the value contained in another Vector... Will a change in one reflect in another?

I have the following two Vector objects in java.
Vector<SomeClass> obj1;
Vector<SomeClass> obj2;
The class SomeClass has an int variable a.
Assume obj2 is empty and obj1 has some elements in it. Suppose I do this:
obj2.add(obj1.firstElement());
obj2.firstElement().a = 10; // obj2.firstElement() will be the object that was
//added above because obj2 was empty at first
Would this change the value of a in obj1.firstElement() too?
Basically I just want to know if these Vector operations are done by reference or value. My guess is that they are done by reference and this change will be reflected in obj1.firstElement() too.
You are right, the reference is copied (shallow copy) and so the change is reflected also in the original vector.
Although is was probably quicker to test this yourself in code then to post it here, you have guessed correctly

Can I change objects in one ArrayList using references in another one?

First array list:- ArrayList<Object> list1;
Second array list:- ArrayList<Object> list2;
Suppose I have filled list1 with some objects.
Now I copy some of objects from list1 using list2.add(list1[i]) and make change to object in list2 using list2[j].setA = something.
Will the corresponding value A of object in list1 change or not?
Actually I want the value A to be changed.
It will change. The lists contain only references to the objects*. So after adding some of the elements in list1 to list2, the two lists will share references to the same physical objects.
*In Java collections you can't store primitive types such as int, only their object counterparts (Integer in this case), always by reference.
A java.util.List (which includes both ArrayList and LinkedList) contains references to objects. That is to say, that if you have a single instance of an object and put that instance in two lists, those two lists will reference the same actual object.
In fact, Java does not have "value objects" unlike some other languages do (i.e. C, C++ and C#). Neither variables nor arrays (and by consequence, any of the collection classes like List) can ever contain objects. They can only contain references to objects.
Here's an example which uses variables to make the functionality clear:
Foo x = new Foo(); // Create a new instance of Foo and assign a reference to it to "x"
Foo y = x; // Copy the reference (not the actual object) to "y"
// At this point, both x and y points to the same object
x.setValue(1); // Set the value to 1
y.setValue(2); // Set the value to 2
System.out.println(x.getValue()); // prints "2"
Now, the exact same is true for lists as well:
List<Foo> listA = new ArrayList<Foo>();
List<Foo> listB = new ArrayList<Foo>();
listA.add(new Foo());
listB.add(listA.get(0));
// The single instance of Foo is now in both lists
listB.get(0).setValue(1);
System.out.println(listA.get(0).getValue()); // Prints "1"
Yes, It will change. In java, you work with the references of objects. so when you put an object in a list, you just put it's reference in list. when you copy it to the other list, you just copy the reference and when you change something, you are using a reference to change the original object. so your original object has been changed.

Categories

Resources