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

Learn what is the difference between list.of and arrays.aslist? with practical examples, diagrams, and best practices. Covers java, list, java-9 development techniques with visual explanations.

List.of vs. Arrays.asList: Understanding Java's Immutable and Resizable Lists

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

Explore the key differences between List.of() (Java 9+) and Arrays.asList() for creating lists in Java, focusing on mutability, null handling, and performance implications.

In Java, there are several ways to create List objects. Two common methods are Arrays.asList() and, since Java 9, List.of(). While both return List instances, their underlying behavior and characteristics are fundamentally different. Understanding these distinctions is crucial for writing robust and efficient Java code, especially concerning mutability and null values.

Arrays.asList(): A Fixed-Size View of an Array

Arrays.asList() was introduced in Java 1.2 and provides a convenient way to convert an array into a List. However, it's important to understand that the List returned by Arrays.asList() is not a standard java.util.ArrayList. Instead, it's a fixed-size wrapper around the original array.

String[] array = {"apple", "banana", "cherry"};
List<String> list = Arrays.asList(array);

System.out.println(list.getClass()); // class java.util.Arrays$ArrayList

// Modifying the list modifies the underlying array
list.set(0, "orange");
System.out.println(Arrays.toString(array)); // [orange, banana, cherry]

// Modifying the array modifies the list
array[1] = "grape";
System.out.println(list); // [orange, grape, cherry]

// Attempting to add/remove elements throws UnsupportedOperationException
try {
    list.add("date");
} catch (UnsupportedOperationException e) {
    System.out.println("Cannot add to fixed-size list: " + e.getMessage());
}

try {
    list.remove(0);
} catch (UnsupportedOperationException e) {
    System.out.println("Cannot remove from fixed-size list: " + e.getMessage());
}

// Null elements are allowed
List<String> nullableList = Arrays.asList("one", null, "three");
System.out.println(nullableList); // [one, null, three]

Demonstrating the behavior of Arrays.asList()

List.of(): An Immutable List (Java 9+)

Introduced in Java 9, List.of() provides a concise way to create immutable lists. These lists are optimized for scenarios where the content will not change after creation. Unlike Arrays.asList(), List.of() creates a truly immutable list, meaning its size and contents cannot be altered.

List<String> immutableList = List.of("apple", "banana", "cherry");

System.out.println(immutableList.getClass()); // class java.util.ImmutableCollections$ListN

// Attempting to modify elements throws UnsupportedOperationException
try {
    immutableList.set(0, "orange");
} catch (UnsupportedOperationException e) {
    System.out.println("Cannot set element in immutable list: " + e.getMessage());
}

// Attempting to add/remove elements throws UnsupportedOperationException
try {
    immutableList.add("date");
} catch (UnsupportedOperationException e) {
    System.out.println("Cannot add to immutable list: " + e.getMessage());
}

// Null elements are NOT allowed
try {
    List<String> nullList = List.of("one", null, "three");
} catch (NullPointerException e) {
    System.out.println("List.of() does not allow null elements: " + e.getMessage());
}

Demonstrating the behavior of List.of()

Key Differences at a Glance

The following diagram summarizes the core distinctions between Arrays.asList() and List.of().

flowchart TD
    A["List Creation Methods"]
    A --> B["Arrays.asList()"]
    A --> C["List.of() (Java 9+)"]

    B --> B1["Returns `java.util.Arrays$ArrayList`"]
    B --> B2["Fixed-size (cannot add/remove)"]
    B --> B3["Mutable elements (can `set()`)"]
    B --> B4["Allows `null` elements"]
    B --> B5["Backed by original array"]

    C --> C1["Returns `java.util.ImmutableCollections$ListN`"]
    C --> C2["Immutable (cannot add/remove/set)"]
    C --> C3["Does NOT allow `null` elements"]
    C --> C4["Not backed by an array"]

    style B fill:#f9f,stroke:#333,stroke-width:2px
    style C fill:#bbf,stroke:#333,stroke-width:2px

Comparison of Arrays.asList() and List.of() characteristics

When to Use Which?

Choosing between Arrays.asList() and List.of() depends entirely on your requirements:

  • Use Arrays.asList() when:

    • You need a List view of an existing array.
    • You intend to modify the elements of the list (which will also modify the underlying array).
    • You need to allow null elements.
    • You are working with older Java versions (pre-Java 9).
  • Use List.of() when:

    • You need an immutable list whose contents will never change.
    • You want to prevent accidental modifications to the list.
    • You do not need to store null elements.
    • You are working with Java 9 or later.
    • You want a more concise way to create small, fixed collections.