I am learning Java and have encountered some inconsistency (due to my lack of knowledge) in the the Collections.reverse()
function. Take this code for example:
// file: Person.java
public class Person {
String name;
int age;
public Person(String name, int age){
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Name: " + name + " Age: " + age;
}
}
// file: Main.java
import java.util.*;
public class Main {
public static void main(String[] args) {
ArrayList<Person> persons1 = new ArrayList<>();
persons1.add(new Person("A", 10));
persons1.add(new Person("B", 12));
persons1.add(new Person("C", 14));
persons1.add(new Person("D", 16));
persons1.add(new Person("E", 18));
ArrayList<Person> persons2 = persons1;
ArrayList<Person> persons3 = new ArrayList<>(persons1);
System.out.println("------------Elements of person1 List [Before]------------");
for (Person p : persons1) {
System.out.println(p);
}
Collections.reverse(persons1);
System.out.println("\n------------Elements of person1 List [After]------------");
for (Person p : persons1) {
System.out.println(p);
}
System.out.println("\n------------Elements of person2 List------------");
for (Person p : persons2) {
System.out.println(p);
}
System.out.println("\n------------Elements of person3 List------------");
for (Person p : persons3) {
System.out.println(p);
}
}
}
Output:
------------Elements of person1 List [Before]------------
Name: A Age: 10
Name: B Age: 12
Name: C Age: 14
Name: D Age: 16
Name: E Age: 18
------------Elements of person1 List [After]------------
Name: E Age: 18
Name: D Age: 16
Name: C Age: 14
Name: B Age: 12
Name: A Age: 10
------------Elements of person2 List------------
Name: E Age: 18
Name: D Age: 16
Name: C Age: 14
Name: B Age: 12
Name: A Age: 10
------------Elements of person3 List------------
Name: A Age: 10
Name: B Age: 12
Name: C Age: 14
Name: D Age: 16
Name: E Age: 18
In the code above, when I reverse the persons1 arraylist, persons2 arraylist is also being reverse, except the persons3 arraylist. It would be great if someone explain me what is happening behind the scenes.
N.B.: I have some understanding of C++ and pointers concepts. Also, I understand creating an instance of a class in Java is equivalent to dynamic allocation in C++. So, what is understand an ArrayList
in Java is like a C++ vector
of pointers allocated in heap dynamically. Therefore, an ArrayList<Person>
is like a dynamically allocated vector<Person *>
. When I am adding a instance of Person
in Java ArrayList
, it is equivalent to pushing back a pointer pointing to a Person
object in heap to the vector of Person pointers. When I am assigning persons1 to persons2 ArrayList, it is equivalent to assigning the pointer to Vector of Person pointers, stored in person1, to persons2. Therefore, reversing the persons1 will also reverse persons2. However, when I am creating a new instance of ArrayList of Person and passed the persons1 as argument in the constructor, I am copying the elements of persons1, that is pointers to Person objects. So, reversing persons1 ArrayList does not change the pointers of Person in persons3 ArrayList. This is what I am guessing by applying my C++ pointers knowledge.
Please correct me if I am wrong.