1

please, I'm having the code shown below:

  public static void main(String[] args) {
    List<String> list1 = new ArrayList<>();
    list1.add("foo");
    System.out.println("\nThis is list 1 : " +list1); //foo

    List<String> list2 = list1;
    System.out.println("\nThis is list 1 : " +list1); // foo
    System.out.println("\nThis is list 2 : " +list2); // foo

    List<String> list3 = new ArrayList<>(list2);
    System.out.println("\nThis is list 3 : " +list3); // foo
    list1.clear();
    System.out.println("\nThis is list 1 : " +list1); // []
    list2.add("bar");
    list3.add("baz");

    System.out.println("\nThis is list 1 : " +list1); // bar
    System.out.println("\nThis is list 2 : " +list2); // bar
    System.out.println("\nThis is list 3 : " +list3); // [foo, baz]

}

output:

**list 1 : [bar], list2 : [bar], list3 : [foo, baz]**

My question is how did list1 get the value bar? because I was thinking it was supposed to be empty at the time. And also, I was thinking that list2 is going to have the values [foo, bar] at this time. Please what is the logic behind this?

1
  • 1
    Because you have one list, List<String> list2 = list1; does not make a new List. Change it to List<String> list2 = new ArrayList<>(list1); for that. Commented Jul 20, 2021 at 3:52

2 Answers 2

5

1 ArrayList, 2 references

Understand that List<String> list1 and List<String> list2 do not hold a list. They hold a reference (pointer) to a list.

Your line:

List<String> list2 = list1;

…copies the contents of list1 (a reference) to list2. You copied the reference (basically a memory address number), not the list.

Your variable list2 points to the same ArrayList object as list1. You have 2 references but only 1 list. So making a change through either reference will be visible through both.

diagram showing two reference variables both pointing to the same ArrayList object

Make a copy

As commented by Elliott Frisch, if you want a copy of a list, pass to the constructor.

List< String > list2 = new ArrayList<>( list1 ) ;  // Make copy of one list by passing to constructor of another.

diagrams of two references pointing to two different list objects

This is a shallow copy, meaning we are copying the references into a new list the original objects to which the references point are not copied. So the references are being copied, not the referents.

List<String> list1 = new ArrayList<>();
list1.add("foo");
System.out.println("list1: " + list1 );          // foo

List<String> list2 = new ArrayList<>( list1 ) ;  // foo
list1.clear();                                   // empty 
list2.add( "bar" );                              // foo, bar
System.out.println( "list1: " +list1 );          // empty
System.out.println( "list2: " +list2 );          // foo, bar

See this code run live at IdeOne.com.

list1: [foo]
list1: []
list2: [foo, bar]

Immutable copy

Or, for an immutable copy, use List.copyOf. If not already immutable, you get a duplicate list.

List< String > list2 = List.copyOf( list1 ) ;  // Creating an immutable copy of the first list, *if* that list is not already immutable.

If a mutable list underlies the immutable list such as with Collections.unmodifiableList, you can combine these two techniques to ensure a separate fresh immutable list is produced.

List<String> list2 = List.copyOf( new ArrayList<>( list1 ) ) ;
Sign up to request clarification or add additional context in comments.

1 Comment

Oh, I got it, thank you so much for the explanation, sir
1

The following statement lets list2 refer to the same list as list1

List<String> list2 = list1;

However,list3 uses another list to initialize itself.

List<String> list3 = new ArrayList<>(list2);

I think that you should know about the difference between shallow and deep copy...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.