ArrayList Contents Modifying Unexpectedly

Pulled an interview question out of an old java certification book I have from back in the day.

Don't want to really want to get into whether of not it is a good interview question or not. Its purpose was as a simple sanity check that the person has worked enough with simple collections in Java ... I did not expect an incorrect answer, anyways, they got it wrong at several steps along the way ... so it served its purpose.

The surprising part to me though was that after putting it in RAD and running it was the output at step 8 ... java is behaving as if list1 after the addAll is not holding the values that were contained in list2, put a reference to the values in list2 ?! Since the clear of list2 altered the contents of list1 ?!?

Yet the modification of list2 prior to the clear at step 7 had no effect on list 1 ... my day's work will now be derailed going through documentation on collection implementation lol ... this was not what I expected at all ... can anyone explain the reasons for the contents of list1 at step 8?

public static void main(String[] args)
{
    List list = new ArrayList();
    System.out.println("1: List1 Post - Constructor\t\t" + list);
    System.out.println();

    list.add("1");
    System.out.println("2: List1 Post - Add 1\t\t\t\t" + list);
    System.out.println();

    list.add("2");
    System.out.println("3: List1 Post - Add 2\t\t\t\t" + list);
    System.out.println();

    list.add(1,"3");
    System.out.println("4: List1 Post - Add three at index 1\t\t" + list);
    System.out.println();

    List list2 = new ArrayList(list);
    System.out.println("5: List1 Post - list2 Constructor\t\t" + list);
    System.out.println("5: List2 Post - list2 Constructor\t\t" + list2);
    System.out.println();

    list.addAll(list2);
    System.out.println("6: List1 Post - Add list2 to list1\t\t" + list);
    System.out.println("6: List2 Post - Add list2 to list1\t\t" +list2);
    System.out.println();

    list2 = list.subList(2,5);
    System.out.println("7: List1 Post - List 2 sublist of list 2,5\t" + list);
    System.out.println("7: List2 Post - List 2 sublist of list 2,5\t" + list2);
    System.out.println();

    list2.clear();
    System.out.println("8: List1 Post - list2 clear\t\t\t" + list);
    System.out.println("8: List2 Post - list2 clear\t\t\t" + list2);
    System.out.println();
}

1: List1 Post - Constructor                 []    
2: List1 Post - Add 1                       [1]    
3: List1 Post - Add 2                       [1, 2]    
4: List1 Post - Add three at index 1        [1, 3, 2]    
5: List1 Post - list2 Constructor           [1, 3, 2]    
5: List2 Post - list2 Constructor           [1, 3, 2]    
6: List1 Post - Add list2 to list1          [1, 3, 2, 1, 3, 2]    
6: List2 Post - Add list2 to list1          [1, 3, 2]    
7: List1 Post - List 2 sublist of list 2,5  [1, 3, 2, 1, 3, 2]    
7: List2 Post - List 2 sublist of list 2,5  [2, 1, 3]    
8: List1 Post - list2 clear                 [1, 3, 2]    
8: List2 Post - list2 clear                 []
Jon Skeet
people
quotationmark

Since the clear of list2 altered the contents of list1

Yes. Because ArrayList.subList is following the documented behaviour of List.subList:

Returns a view of the portion of this list between the specified fromIndex, inclusive, and toIndex, exclusive. (If fromIndex and toIndex are equal, the returned list is empty.) The returned list is backed by this list, so non-structural changes in the returned list are reflected in this list, and vice-versa. The returned list supports all of the optional list operations supported by this list.

This method eliminates the need for explicit range operations (of the sort that commonly exist for arrays). Any operation that expects a list can be used as a range operation by passing a subList view instead of a whole list. For example, the following idiom removes a range of elements from a list:

 list.subList(from, to).clear();

That specifically gives an example of removing a portion of a list by calling clear on a sublist view.

people

See more on this question at Stackoverflow