Comparing Unmodifiable Lists and List Views
There are subtle differences to be aware of between unmodifiable lists and list views.
- Backing an array
The Arrays.asList() method returns a fixed-size list view that is backed by the array passed as an argument so that any changes made to the array are reflected in the view list as well. This is not true of the List.of() and List.ofCopy() methods, as they create unmodifiable lists which are not backed by any argument array that is passed either explicitly or implicitly as a variable arity parameter.
In the code below, we see that the list view returned by the Arrays.asList() method reflects the change at (1) in its backing array, but not the unmodifiable list returned by the List.of() method at (2) when its argument array is modified.
Integer[] yrArray1 = {2020, 2021, 2022};
List<Integer> yrlist1 = Arrays.asList(yrArray1);
yrArray1[0] = 2019; // Modify the array
out.println(“yrArray1: ” + Arrays.toString(yrArray1)); // [2019, 2021, 2022]
out.println(“yrlist1: ” + yrlist1); // (1) [2019, 2021, 2022]
Integer[] yrArray2 = {2020, 2021, 2022};
List<Integer> yrlist2 = List.of(yrArray2);
yrArray2[0] = 2019; // Modify the array
out.println(“yrArray2: ” + Arrays.toString(yrArray2)); // [2019, 2021, 2022]
out.println(“yrlist2: ” + yrlist2); // (2) [2020, 2021, 2022]
- Mutability
The list view returned by the Arrays.asList() method is mutable, but it cannot be structurally modified. In contrast, the unmodifiable list returned by the List.of() method is immutable.
In the code below, only the list view returned by the Arrays.asList() method can be modified as shown at (1), but an attempt to modify the unmodifiable list returned by the List.of() method at (2) throws an exception.
List<Integer> yrList3 = Arrays.asList(2020, 2021, 2022);
yrList3.set(2, 2023); // (1) OK
out.println(yrList3); // [2020, 2021, 2023]
List<Integer> yrlist4 = List.of(2020, 2021, 2022);
yrlist4.set(2, 2023); // (2) UnsupportedOperationException
However, both lists will throw an exception if an attempt is made to change them structurally—that is, add or remove elements from the list:
yrList3.add(2050); // UnsupportedOperationException
yrlist4.remove(0); // UnsupportedOperationException
- The null value
The Arrays.asList() method allows null elements, whereas the List.of() and List.ofCopy() methods do not.
List<Integer> yrList5 = Arrays.asList(2020, 2021, null); // OK.
List<Integer> yrlist6 = List.of(2020, 2021, null); // NullPointerException
The behavior of the List.contains() method when passed the null value is dependent on which method created the list.
boolean flag1 = Arrays.asList(2021, 2022).contains(null); // OK.
boolean flag2 = List.of(2021, 2022).contains(null); // NullPointerException
Leave a Reply