asList method returns a type of ArrayList that is different from java. util. ArrayList. The main difference is that the returned ArrayList only wraps an existing array — it doesn't implement the add and remove methods.
The asList() method of java. util. Arrays class is used to return a fixed-size list backed by the specified array. This method acts as a bridge between array-based and collection-based APIs, in combination with Collection.
The java.util.Arrays.asList(T... a) returns a fixed-size list backed by the specified array. ( Changes to the returned list "write through" to the array.)
How is Arrays. asList() different than the standard way of initialising List? Explanation: List returned by Arrays. asList() is a fixed length list which doesn't allow us to add or remove element from it.
Arrays.asList
returns a mutable list while the list returned by List.of
is immutable:
List<Integer> list = Arrays.asList(1, 2, null);
list.set(1, 10); // OK
List<Integer> list = List.of(1, 2, 3);
list.set(1, 10); // Fails with UnsupportedOperationException
Arrays.asList
allows null elements while List.of
doesn't:
List<Integer> list = Arrays.asList(1, 2, null); // OK
List<Integer> list = List.of(1, 2, null); // Fails with NullPointerException
contains
behaves differently with nulls:
List<Integer> list = Arrays.asList(1, 2, 3);
list.contains(null); // Returns false
List<Integer> list = List.of(1, 2, 3);
list.contains(null); // Fails with NullPointerException
Arrays.asList
returns a view of the passed array, so the changes to the array will be reflected in the list too. For List.of
this is not true:
Integer[] array = {1,2,3};
List<Integer> list = Arrays.asList(array);
array[1] = 10;
System.out.println(list); // Prints [1, 10, 3]
Integer[] array = {1,2,3};
List<Integer> list = List.of(array);
array[1] = 10;
System.out.println(list); // Prints [1, 2, 3]
Arrays.asList
and List.of
See the JavaDocs and this talk by Stuart Marks (or previous versions of it).
I'll be using the following for the code examples:
List<Integer> listOf = List.of(...);
List<Integer> asList = Arrays.asList(...);
List<Integer> unmodif = Collections.unmodifiableList(asList);
Any attempt to structurally change List.of
will result in an UnsupportedOperationException
. That includes operations such as add, set and remove. You can, however, change the contents of the objects in the list (if the objects are not immutable), so the list is not "completely immutable".
This is the same fate for unmodifiable lists created with Collections.unmodifiableList
. Only this list is a view of the original list, so it can change if you change the original list.
Arrays.asList
is not completely immutable, it does not have a restriction on set
.
listOf.set(1, "a"); // UnsupportedOperationException
unmodif.set(1, "a"); // UnsupportedOperationException
asList.set(1, "a"); // modified unmodif! unmodif is not truly unmodifiable
Similarly, changing the backing array (if you hold it) will change the list.
Structural immutability comes with many side-effects related to defensive coding, concurrency and security which are beyond the scope of this answer.
List.of
and any collection since Java 1.5 do not allow null
as an element. Attempting to pass null
as an element or even a lookup will result in a NullPointerException
.
Since Arrays.asList
is a collection from 1.2 (the Collections Framework), it allows null
s.
listOf.contains(null); // NullPointerException
unmodif.contains(null); // allowed
asList.contains(null); // allowed
Since List.of
has been introduced in Java 9 and the lists created by this method have their own (binary) serialized form, they cannot be deserialized on earlier JDK versions (no binary compatibility). However, you can de/serialize with JSON, for example.
Arrays.asList
internally calls new ArrayList
, which guarantees reference inequality.
List.of
depends on internal implementation. The instances returned can have reference equality, but since this is not guaranteed you can not rely on it.
asList1 == asList2; // false
listOf1 == listOf2; // true or false
Worth mentioning that lists are equal (via List.equals
) if they contain the same elements in the same order, regardless of how they were created or what operations they support.
asList.equals(listOf); // true i.f.f. same elements in same order
If the number of elements in the list of List.of
is 2 or less, the elements are stored in fields of a specialized (internal) class. An example is the list that stores 2 elements (partial source):
static final class List2<E> extends AbstractImmutableList<E> {
private final E e0;
private final E e1;
List2(E e0, E e1) {
this.e0 = Objects.requireNonNull(e0);
this.e1 = Objects.requireNonNull(e1);
}
}
Otherwise they are stored in an array in a similar fashion to Arrays.asList
.
The List.of
implementations which are field-based (size<2) perform slightly faster on some operations. As examples, size()
can return a constant without fetching the array length, and contains(E e)
does not require iteration overhead.
Constructing an unmodifiable list via List.of
is also faster. Compare the above constructor with 2 reference assignments (and even the one for arbitrary amount of elements) to
Collections.unmodifiableList(Arrays.asList(...));
which creates 2 lists plus other overhead. In terms of space, you save the UnmodifiableList
wrapper plus some pennies. Ultimately, the savings in the HashSet
equivalent are more convincing.
Conclusion time: use List.of
when you want a list that doesn't change and Arrays.asList
when you want a list that can change (as shown above).
Let summarize the differences between List.of and Arrays.asList
List.of
can be best used when data set is less and unchanged, while Arrays.asList
can be used best in case of large and dynamic data set.
List.of
take very less overhead space because it has field-based implementation and consume less heap space, both in terms of fixed overhead and on a per-element basis. while Arrays.asList
take more overhead space because while initialization it creates more objects in heap.
Collection returned by List.of
is immutable and hence thread-safe while Collection returned by Arrays.asList
is mutable and not thread safe.
(Immutable collection instances generally consume much less memory than their mutable counterparts.)
List.of
doesn't allow null elements while Arrays.asList
allows null elements.
Apart from the above answers there are certain operations on which both List::of
and Arrays::asList
differ:
+----------------------+---------------+----------+----------------+---------------------+
| Operations | SINGLETONLIST | LIST::OF | ARRAYS::ASLIST | JAVA.UTIL.ARRAYLIST |
+----------------------+---------------+----------+----------------+---------------------+
| add | ❌ | ❌ | ❌ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| addAll | ❌ | ❌ | ❌ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| clear | ❌ | ❌ | ❌ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| remove | ❌ | ❌ | ❌ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| removeAll | ❗️ | ❌ | ❗️ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| retainAll | ❗️ | ❌ | ❗️ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| replaceAll | ❌ | ❌ | ✔️ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| set | ❌ | ❌ | ✔️ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| sort | ✔️ | ❌ | ✔️ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| remove on iterator | ❌ | ❌ | ❌ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| set on list-iterator | ❌ | ❌ | ✔️ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
More about Collections::singletonList Vs. List::of
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With