How to Convert an Array to an ArrayList in Java
Converting an array to an ArrayList is one of the most common tasks in Java. Although Java provides the convenient Arrays.asList() method, it comes with a well-known limitation that surprises many developers: the returned list is fixed in size and does not support operations such as add() or remove().
To create a fully mutable ArrayList, you need to use a different approach. In this tutorial, you'll learn several ways to convert an array into an ArrayList, understand the famous Arrays.asList() gotcha, and discover how to correctly handle primitive arrays like int[].
Problem Statement
Given the following array:
Integer[] numbers = {10, 20, 30};
Convert it into a mutable ArrayList<Integer> that supports operations such as:
add()remove()set()
Method 1: Using Arrays.asList() (Fixed-Size List)
The simplest conversion uses Arrays.asList().
Example
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
Integer[] numbers = {10, 20, 30};
List<Integer> list = Arrays.asList(numbers);
System.out.println(list);
}
}
Output
[10, 20, 30]
Important Limitation
Although this looks like an ArrayList, it is not a resizable list.
Attempting to add an element:
list.add(40);
produces:
Exception in thread "main"
java.lang.UnsupportedOperationException
Explanation
Arrays.asList() returns a fixed-size list backed by the original array.
You can replace existing elements using set(), but you cannot change the size of the list.
Method 2: Wrap in a New ArrayList (Recommended)
If you need a fully mutable list, wrap the result of Arrays.asList() inside an ArrayList.
Example
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
Integer[] numbers = {10, 20, 30};
List<Integer> list =
new ArrayList<>(Arrays.asList(numbers));
list.add(40);
System.out.println(list);
}
}
Output
[10, 20, 30, 40]
Explanation
The constructor copies all elements into a new internal array.
The new ArrayList is completely independent of the original array.
Time Complexity: O(n)
Space Complexity: O(n)
Method 3: Using Collections.addAll()
Another common approach is to create an empty ArrayList and add every array element.
Example
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static void main(String[] args) {
Integer[] numbers = {10, 20, 30};
List<Integer> list = new ArrayList<>();
Collections.addAll(list, numbers);
System.out.println(list);
}
}
Output
[10, 20, 30]
Explanation
Collections.addAll() efficiently copies every element from the array into the list.
The resulting ArrayList is fully mutable.
Method 4: Using Java Streams
Streams provide a concise and modern approach.
Example
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
Integer[] numbers = {10, 20, 30};
List<Integer> list = Arrays.stream(numbers)
.collect(Collectors.toList());
System.out.println(list);
}
}
Output
[10, 20, 30]
Explanation
The stream processes each array element and collects them into a list.
This approach is especially useful when additional stream operations are required.
The Primitive Array Trap
One of the most famous Java pitfalls involves primitive arrays.
Consider:
int[] numbers = {10, 20, 30};
List<int[]> list = Arrays.asList(numbers);
System.out.println(list.size());
Output
1
Instead of three elements, the list contains one element, which is the entire int[].
Why Does This Happen?
Arrays.asList() works with reference types.
Since int is a primitive type, Java treats the entire int[] as one object instead of three separate elements.
Correct Way
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
int[] numbers = {10, 20, 30};
List<Integer> list = Arrays.stream(numbers)
.boxed()
.collect(Collectors.toList());
System.out.println(list);
}
}
Output
[10, 20, 30]
The boxed() method converts each primitive int into an Integer.
Step-by-Step Explanation
Suppose the array is:
[10, 20, 30]
Using:
Arrays.asList(numbers)
creates a fixed-size list:
[10, 20, 30]
Calling:
list.add(40);
fails because the list cannot grow.
Wrapping it:
new ArrayList<>(Arrays.asList(numbers))
creates an independent, resizable list.
Now:
list.add(40);
produces:
[10, 20, 30, 40]
Internal Working
Arrays.asList()
Array
↓
Fixed-size List
↓
Same underlying storage
Changing an element using set() affects both the array and the list.
Adding or removing elements is not allowed.
New ArrayList
Array
↓
Copy Elements
↓
Independent ArrayList
The new list has its own storage and supports every standard ArrayList operation.
Real-Life Analogy
Imagine borrowing a shelf from someone else.
With Arrays.asList(), you can rearrange the books already on the shelf, but you cannot make the shelf larger or smaller.
Creating a new ArrayList is like buying your own expandable bookshelf and copying all the books onto it.
Now you can freely add or remove books without affecting the original shelf.
Best Practices
- Use
new ArrayList<>(Arrays.asList(array))when you need a mutable list. - Never pass primitive arrays directly to
Arrays.asList(). - Use
boxed()when converting primitive arrays. - Use
Collections.addAll()when you already have an empty list. - Use streams when additional stream operations are required.
Common Mistakes
1. Assuming Arrays.asList() Returns a Normal ArrayList
It returns a fixed-size list.
Adding or removing elements throws an exception.
2. Passing Primitive Arrays Directly
Incorrect:
Arrays.asList(intArray);
Correct:
Arrays.stream(intArray)
.boxed()
.collect(Collectors.toList());
3. Assuming Arrays.asList() Creates a Copy
The returned list shares the same backing array.
Using set() modifies the original array.
4. Missing Required Imports
Remember to import:
java.util.ArrayList
java.util.Arrays
java.util.Collections
java.util.List
Expert Tips
- The primitive-array behavior of
Arrays.asList()is one of Java's most frequently asked interview questions. - If you only need a read-only or fixed-size view of an array,
Arrays.asList()is perfectly acceptable. - For very large arrays, remember that creating a new
ArrayListcopies every element, which requires additional memory. - Streams are especially useful when conversion is part of a larger processing pipeline.
Comparison Table
| Method | Mutable Result? | Works with Primitive Arrays? |
|---|---|---|
Arrays.asList() |
❌ No (Fixed Size) | ❌ No |
new ArrayList<>(Arrays.asList()) |
✅ Yes | ❌ No |
Collections.addAll() |
✅ Yes | ❌ No |
Arrays.stream().boxed().collect() |
✅ Yes | ✅ Yes |
Frequently Asked Questions
1. Why can't I add elements to a list created with Arrays.asList()?
Because it returns a fixed-size list backed by the original array, so its size cannot change.
2. How do I create a mutable ArrayList from an array?
Wrap the result of Arrays.asList() inside:
new ArrayList<>(Arrays.asList(array))
3. Why does Arrays.asList(intArray) produce a list of size 1?
Because Java treats the entire primitive array as a single object rather than individual elements.
4. How do I convert an int[] to a List<Integer>?
Use:
Arrays.stream(intArray)
.boxed()
.collect(Collectors.toList());
5. Does modifying a list returned by Arrays.asList() affect the original array?
Yes.
Calling set() updates both because they share the same backing array.
6. Is Collections.addAll() better than wrapping Arrays.asList()?
Both approaches are efficient.
Choose the one that best fits your coding style.
7. Can I convert a 2D array into a list?
Yes.
Convert each inner array separately using loops or streams.
8. What is the difference between List and ArrayList in this context?
Arrays.asList() returns a List implementation with a fixed size.
new ArrayList<>() creates a fully resizable ArrayList that supports all standard modification operations.