coding
ArrayList

Initialization of an ArrayList in one line

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In Java, initializing an ArrayList in one line is easy, but the best syntax depends on whether you want a mutable list, an immutable list, or a quick demo-only shortcut. The most practical answer in modern Java is usually to wrap List.of(...) or Arrays.asList(...) inside new ArrayList<>(...) when you need mutability.

Mutable ArrayList in One Line

If you want a real, resizable ArrayList, this is the common pattern:

java
1import java.util.ArrayList;
2import java.util.List;
3
4ArrayList<String> names = new ArrayList<>(List.of("Alice", "Bob", "Carol"));

This creates a mutable ArrayList populated with the given values. You can still call add, remove, or clear afterward.

For older Java versions, Arrays.asList is the equivalent source list:

java
1import java.util.ArrayList;
2import java.util.Arrays;
3
4ArrayList<String> names = new ArrayList<>(Arrays.asList("Alice", "Bob", "Carol"));

Immutable List Versus Mutable ArrayList

If you do not actually need an ArrayList, the simpler answer may be an immutable List.

java
import java.util.List;

List<String> names = List.of("Alice", "Bob", "Carol");

That is shorter and clearer, but it is not an ArrayList and it cannot be modified.

This distinction matters because many code examples say "ArrayList" when they really mean "a list of values." If the code never mutates the collection, List.of may be the better API.

Why Double-Brace Initialization Is Usually Avoided

You may also see this older pattern:

java
1ArrayList<String> names = new ArrayList<String>() {{
2    add("Alice");
3    add("Bob");
4    add("Carol");
5}};

It works, but it creates an anonymous inner class and has awkward side effects around serialization, class generation, and hidden references. It is generally not recommended for production code.

That is why modern Java code tends to prefer constructor wrapping around List.of or Arrays.asList instead.

Streams Are Possible but Usually Overkill

A stream-based one-liner also works:

java
1import java.util.ArrayList;
2import java.util.stream.Collectors;
3import java.util.stream.Stream;
4
5ArrayList<String> names = Stream.of("Alice", "Bob", "Carol")
6    .collect(Collectors.toCollection(ArrayList::new));

This is valid, but it is more verbose than necessary for static literal values. Streams make more sense when the elements are being computed or transformed rather than just listed.

Prefer the Interface When the Concrete Type Does Not Matter

Even when you create an ArrayList, it is often cleaner to declare the variable as List.

java
1import java.util.ArrayList;
2import java.util.List;
3
4List<String> names = new ArrayList<>(List.of("Alice", "Bob", "Carol"));

This keeps the code flexible. If you later switch to another List implementation, the rest of the code does not need to care as long as it only depends on list behavior.

Practical Decision Rule

Use these rules:

  • want a mutable ArrayList: new ArrayList<>(List.of(...))
  • need Java 8 compatibility: new ArrayList<>(Arrays.asList(...))
  • want an immutable list: List.of(...)
  • avoid double-brace initialization unless you have a very specific reason

That keeps the code short without introducing unnecessary complexity.

Common Pitfalls

  • Using Arrays.asList(...) directly and then trying to add or remove elements causes runtime errors because the returned list is fixed-size. Wrap it in new ArrayList<>(...) if you need mutability.
  • Confusing List.of(...) with ArrayList leads to immutable collections where the code expects a resizable list. Choose the type based on whether mutation is required.
  • Using double-brace initialization for convenience creates an anonymous class and hidden overhead. It is usually not worth the side effects.
  • Reaching for streams to build a literal list makes simple code harder to read. Use streams when there is actual transformation logic, not just static values.
  • Declaring the variable as ArrayList when only List behavior is needed can make the code more rigid than necessary. Prefer the interface type unless the concrete type matters.

Summary

  • The usual one-line mutable ArrayList pattern is new ArrayList<>(List.of(...)).
  • For older Java versions, new ArrayList<>(Arrays.asList(...)) is common.
  • 'List.of(...) is concise but immutable.'
  • Double-brace initialization works but is usually discouraged.
  • Pick the form based on mutability needs, not just on brevity.

Course illustration
Course illustration

All Rights Reserved.