Reputation: 1081
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
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
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 implementsRandomAccess
.
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
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
Reputation: 1032
Arrays has its own implementations of ArrayList which does not make a copy of array from toList
Upvotes: 1