-1

As if we pass predefined list to the new ArrayList constructor it will SHALLOW-COPY that list which means reference to that list , so if we modify the new list ,the changes should also tends to modify at the old list .but in this programme it isnot the case .... WHY?

public class testArrayList {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);

        List<Integer> list2 = new ArrayList<>(list);

        list.add(3);
        System.out.println(list2.get(2));

    }
}

It is giving me out of bound exception.. WHY?

sparsh goyal
  • 89
  • 1
  • 7
  • The ArrayList constructor creates a shallow copy of the `contents` of the list... so the contents of the list point to the same objects.... Integer is a bad example though because it is immutable – RobOhRob Oct 18 '19 at 14:35
  • When the constructor performs a shallow copy, but the new list is still affected by changes on the other list (not its items), then what has been copied by the constructor to earn the name "shallow _copy_"? – Tom Oct 18 '19 at 14:47

5 Answers5

4

By doing:

List<Integer> list2 = new ArrayList<>(list);

You are creating a copy of the list. Here's a simplified version of the constructor code of ArrayList:

public ArrayList(Collection<? extends E> c) {
    elementData = c.toArray();
    if ((size = elementData.length) != 0) {
        // List copy is performed here!
        elementData = Arrays.copyOf(elementData, size, Object[].class);
    } else {
        this.elementData = EMPTY_ELEMENTDATA;
    }
}

What you want to do is:

List<Integer> list2 = list1

Which simply copies the reference.

Nicolas
  • 6,611
  • 3
  • 29
  • 73
3

Calling that constructor will make a new list that references the same Items, but it won't be backed by the same list. Therefore you can add and remove from your new list without impacting the old one. If however you had some Dataobjects, those would still be manipulated no matter in which list you access them.

Marcel
  • 1,509
  • 1
  • 17
  • 39
0

A shallow copy means that it will still make a copy of the list in a separate memory location, but if there are further collections within the list, it will copy references to those rather than copying recursively. That is why you get an out of bounds error - the 3 is only added to the first list and not the second, because they now exist as two entirely separate lists. The copy constructor you are using is described in the API as:

(ArrayList(Collection<? extends E> c): Constructs a list containing the elements of the specified collection, in the order they are returned by the collection's iterator.

If you do just want to copy the reference, you can use the assignment operator rather than a copy constructor:

List<Integer> list2 = list1;
Rob Streeting
  • 1,675
  • 3
  • 16
  • 27
0
List<Integer> list2 = (list);

Then add to the list, it's effect in list2, which is Shallow-Copy, if you use Constructor, it's like Deep-copy...

Ganesh
  • 169
  • 6
0

From ArrayList.class:

public ArrayList(Collection<? extends E> c) {
        this.elementData = c.toArray();
        if ((this.size = this.elementData.length) != 0) {
            if (this.elementData.getClass() != Object[].class) {
                this.elementData = Arrays.copyOf(this.elementData, this.size, Object[].class);
            }
        } else {
            this.elementData = EMPTY_ELEMENTDATA;
        }

    }

This is the way ArrayList constructor is implemented. All elements are copied and new ArrayList is creating. If you want to copy reference to old list you should do it like this:

List<Integer> list2 = list;