8 Ways to Create a List in Java: From Mutable to Immutable
Java offers a surprising variety of ways to initialize a list. Choosing the right one depends on whether you need to modify the data later or if you want to ensure the list remains "read-only."
Here are 8 common methods to get the job done, categorized by their mutability.
Mutable Lists (Modifiable)
These lists allow you to add, remove, or update elements after initialization.
1. The Classic ArrayList
The most common approach. It’s simple, efficient, and fully modifiable.
List<String> mutableList = new ArrayList<>();
mutableList.add("E1");
mutableList.add("E2");
2. Arrays.asList() (The "Hybrid")
This creates a list backed by the original array. While you can update existing elements, you cannot add or remove elements (it will throw an UnsupportedOperationException).
List<String> listBackedByArrays = Arrays.asList("E1", "E2");
3. Double-Brace Initialization
An older "hack" that creates an anonymous inner class. While concise, it's often discouraged because it can lead to memory leaks and unnecessary class creation.
List<String> cities = new ArrayList<>() {{
add("New York");
add("Rio");
add("Tokyo");
}};
4. Java Streams (Collectors.toList)
Ideal when you are transforming or filtering data. By default, Collectors.toList() usually returns a mutable ArrayList, though this isn't strictly guaranteed by the spec.
List<String> list = Stream.of("foo", "bar").collect(Collectors.toList());
Immutable Lists (Read-Only)
Use these when you want to prevent any changes to the collection, ensuring thread safety and data integrity.
5. Collections.unmodifiableList
This acts as a wrapper. It takes an existing mutable list and returns a read-only view of it.
List<Integer> unmodif = Collections.unmodifiableList(new ArrayList<>());
6. Collections.singletonList
A memory-efficient way to create a list containing exactly one element. It is immutable and fixed-size.
List<String> singleValueList = Collections.singletonList("E1");
7. List.of() (The Modern Standard)
Introduced in Java 9, this is the cleanest way to create small, immutable lists. It’s concise and highly optimized.
List<String> immutableListJava9 = List.of("E1", "E2");
8. Stream.toUnmodifiableList()
Introduced in Java 10, this allows you to process a stream and ensure the final result is strictly immutable.
List<Integer> list = Stream.of(42).collect(Collectors.toUnmodifiableList());