Charan
Charan

Reputation: 1081

Created two Lists from same array, Modifying one List, changes the other

I created two list from same array and sorted one of them. When I tried to change one list, other list also got updated.

List<Integer> list = Arrays.asList(ar);
List<Integer> sorted = Arrays.asList(ar);
Collections.sort(sorted);
list.set(0,10000000); //changes sorted also

It took me a while figure out, below mentioned code worked.

List<Integer> sorted = new ArrayList<Integer>(Arrays.asList(ar));

I want to know why my first approach didn't work? I created two separate lists, why the changes are taking place in both of them. How does java assign values to variables here?

Upvotes: 9

Views: 2093

Answers (4)

Shashank Shekhar
Shashank Shekhar

Reputation: 11

list & sorted are still pointing to the same memory address of ar in the first approach while in the second approach a new memory address has been allocated after calling a constructor a new memory block is allocated to the class object.

Upvotes: 0

Sunde
Sunde

Reputation: 343

From the Java documentation for Arrays.asList:

Returns a fixed-size list backed by the specified array. (Changes to the returned list "write through" to the array.) This method acts as bridge between array-based and collection-based APIs, in combination with Collection.toArray(). The returned list is serializable and implements RandomAccess.

So when you change something in list, it "writes through" to the underlying array, ar, which is also the underlying array in sorted, so the change is reflected in sorted as well.

Also, the code for asList is:

public static <T> List<T> asList(T... a) {
    return new ArrayList<T>(a);
}

This is java.util.Arrays.ArrayList, which has the following definition:

ArrayList(E[] array) {
    a = Objects.requireNonNull(array);
}

What is important is that a is not copied, it is the original array. The java.util.ArrayList class has the following constructor

public ArrayList(Collection<? extends E> c) {
     elementData = c.toArray();
     size = elementData.length;
     // c.toArray might (incorrectly) not return Object[] (see 6260652)
     if (elementData.getClass() != Object[].class)
         elementData = Arrays.copyOf(elementData, size, Object[].class);
 }

so in the java.util.ArrayList constructor, we create copies of each element, and in java.util.Arrays.ArrayList, we do not.

Upvotes: 11

Jonathan Rosenne
Jonathan Rosenne

Reputation: 2217

A List is a collection of objects, and both list are collections of the same objects. The set statement changes an object, and the object is shared by both lists.

I don't understand why the second version works.

Upvotes: 1

krzydyn
krzydyn

Reputation: 1032

Arrays has its own implementations of ArrayList which does not make a copy of array from toList

Upvotes: 1

Related Questions