What is the difference between List.of and Arrays.asList?

We Are Going To Discuss About What is the difference between List.of and Arrays.asList?. So lets Start this Java Article.

What is the difference between List.of and Arrays.asList?

1. What is the difference 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.

2. What is the difference 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.

Solution 1

`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]
``````

Original Author ZhekaKozlov Of This Content

The differences between `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);
``````

Structural immutability (Or: unmodifiability)

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.

Null hostility

`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
``````

Serialized form

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.

Identity

`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
``````

Implementation (warning: details can change over versions)

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`.

Time and Space efficiency

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).

Original Author user1803551 Of This Content

Solution 3

Let summarize the differences between List.of and Arrays.asList

1. `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.

2. `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.

3. 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.)

4. `List.of` doesn’t allow null elements while `Arrays.asList` allows null elements.

Original Author Mohit Tyagi Of This Content

Solution 4

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 |       ❌      |     ❌  |        ✔️       |          ✔️          |
+----------------------+---------------+----------+----------------+---------------------+
``````
1. ✔️ means the method is supported
2. ❌ means that calling this method will throw an
UnsupportedOperationException
3. ❗️ means the method is supported only if the method’s arguments do
not cause a mutation, e.g.
Collections.singletonList(“foo”).retainAll(“foo”) is OK but
Collections.singletonList(“foo”).retainAll(“bar”)throws an
UnsupportedOperationException