Comparing Unmodifiable Lists and List Views – Collections, Part I: ArrayList

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.

Click here to view code image

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.

Click here to view code image

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:

Click here to view code image

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.

Click here to view code image

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.

Click here to view code image

boolean flag1 = Arrays.asList(2021, 2022).contains(null); // OK.
boolean flag2 = List.of(2021, 2022).contains(null);       // NullPointerException

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *