Search code examples
javaarraylistpass-by-referencepass-by-value

Java ArrayList independent copy


I used the method below to make a copy of a list, as you can see the output, they are independent. Did I get something wrong? or are they really independent? because I did some research on the internet, and it told me this method should pass-by-reference (which list 'a' and 'copy' should be dependent).

public static void main(String[] args) {
    ArrayList<String> a = new ArrayList<>(Arrays.asList("X", "X"));
    ArrayList<String> copy = new ArrayList<>(a);
    copy.set(0, "B");
    copy.remove(copy.size()-1);
    System.out.println(a);
    System.out.println(copy);
}

Output:

[X, X]
[B]

Solution

  • Yes, this method should pass-by-reference (which list 'a' and 'copy' should be dependent). But these two operations don't prove this.

    copy.set(0, "B");
    copy.remove(copy.size()-1);
    

    See if the following code helps you understand:

    
        public static void main(String[] args) {
            Process process = new Process(1);
            Process process2 = new Process(2);
            ArrayList<Process> a = new ArrayList<>(Arrays.asList(process, process2));
            ArrayList<Process> copy = new ArrayList<>(a);
            copy.get(0).id = 10;
    
            // This proves that both ArrayLists maintain the same Process object at this point
            // output:
            // [Id:10, Id:2]
            // [Id:10, Id:2]
            System.out.println(a);
            System.out.println(copy);
    
    
            // copy.remove(copy.size() - 1) or copy.set(0, process3) doesn't affect another ArrayList
            Process process3 = new Process(3);
            process3.id = 100;
            copy.set(0, process3);
            copy.remove(copy.size() - 1);
            // output:
            // [Id:10, Id:2]
            // [Id:100]
            System.out.println(a);
            System.out.println(copy);
    
        }
    
        static class Process {
            public int id;
    
            public Process(int id) {
                this.id = id;
            }
    
            @Override
            public String toString() {
                return "Id:" + id;
            }
        }