I have below two situations related to ArrayList get
method, one with custom class and one with String class:
1. Below is the example of modifying Custom class ArrayList element:
ArrayList<MyClass> mTmpArray1 = new ArrayList<MyClass>();
MyClass myObj1 = new MyClass(10);
mTmpArray1.add(myObj1);
MyClass myObj2 = mTmpArray1.get(0);
myObj2.myInt = 20;
MyClass myObj3 = mTmpArray1.get(0);
Log.d(TAG, "Int Value:"+myObj3.myInt); // Prints "20"
2. And below is the example of modifying String ArrayList element:
ArrayList<String> mTmpArray2 = new ArrayList<String>();
mTmpArray2.add("Test_10");
String myStr1 = mTmpArray2.get(0);
myStr1 = "Test_20";
String myStr2 = mTmpArray2.get(0);
Log.d(TAG, "Str Value:"+myStr2); // Prints "Test_10"
So in case of MyClass ArrayList, when I call get
and modify the value, then I see change is reflecting when I do get
again.
But same way when I modify String ArrayList, then changes are not reflecting.
What is the different in of the get
method in both the scenarios?
Is it that in case of String, String class creating deep copy and returns new object, and in case of Custom class shallow copy is created?
In the first scenario applicable to "LinkedHashMap", "HashMap" and "List"?
An ArrayList does not check for duplicates, you could stuff the same object in there over and over again.
One more way to detect duplication in the java array is adding every element of the array into HashSet which is a Set implementation. Since the add(Object obj) method of Set returns false if Set already contains an element to be added, it can be used to find out if the array contains duplicates in Java or not.
Duplicate items can be removed from the ArrayList by using a HashSet as duplicate items are not allowed in a HashSet. So the ArrayList is converted into a HashSet and that removes the duplicate items. Then the HashSet is converted back into an ArrayList.
Your are not doing the same thing in the two cases.
Here you update the state of an object, so the change affects the object stored in the list :
myObj2.myInt = 20;
Here you are assigning a new object to a local variable, so the list is not affected :
myStr1 = "Test_20";
If String
was mutable, you could have modified the String by calling some method, and the change would have been reflected in the object stored in the list :
myStr1.setSomething(...);
On the other hand, if in the first case you would have changed the value of the local variable, the object stored in the list wouldn't have been affected :
myObj2 = new MyClass (...);
Strings are immutable. You're not inserting the new string into the array list.
When you do String myStr2 = mTmpArray2.get(0);
, even tho you are pointing to a reference in the ArrayList, any attempt to change the value, will (because of String immutability) create a new String (myStr2) that will not reference the ArrayList anymore.
When you do myStr1 = "xxx"
, you're not actually changing the ArrayList reference, you're changing a new (copy) (now called myStr1) that was grabbed from the ArrayList and it has a local scope.
Read some more about Strings: Immutability of Strings in Java
Now in the first example, you are pointing to a mutable object (your custom class) so you're literally changing the direct value, through the reference. Welcome to Java. ;)
Unrelated: This code: MyClass myObj1 = new MyClass(10);
is (arguably) considered bad. It's better to use a factory pattern that is a lot easier to read. In other words, public constructors with parameters are hard to read (for example, I have no idea what I am constructing when I read your code).
A (perhaps) better approach would be: MyClass myObj = MyClass.createInstanceWithCapacity(10); // i've invented the name because I don't know what your 10 is, but look at both, which one do you think is easier to understand upon first glance?
Disclaimer: The above unrelated comment is my personal opinion and not all developers will agree. ;)
Strings have very nice property called "Immutablity"
This means that String cannot be mutable (changed), when we create/ try to refer to old string, a new instance string is created. And any changes we do are saved in new instance and it do not affect the old string
For example,
String s = "Old String";
System.out.println("Old String : "+s); // output : Old String
String s2 = s;
s2 = s2.concat(" made New");
System.out.println("New String : "+s2); // output : Old String made New
System.out.println("Old String is not changed : "+s); // output : Old String
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With