When learning Java, understanding arrays and ArrayList is essential. At first glance they both hold sequences of data, but they have important differences in size, flexibility, type support, and performance. This article explains the difference between array and ArrayList in Java, with examples, pros and cons, and guidance on when to use each.
What Is an Array in Java?
A Java array is a built-in data structure. It’s fixed‑size: once created, its length cannot change. Arrays support both primitive types (e.g. int
, char
) and object references (e.g. String
, custom classes). Elements are stored in contiguous memory; primitive arrays store actual values directly, object arrays store references.
Access is via simple indexing using []
syntax. Syntax examples:
javaCopyEditint[] arr = new int[5];
String[] names = {"Alice", "Bob", "Carol"};
What Is an ArrayList in Java?
An ArrayList is part of the Java Collections Framework (java.util
) and implements the List
interface.
- It is dynamic in size: grows automatically as elements are added.
- Stores only object references, not primitives; uses autoboxing for types like
int
toInteger
. - Provides built‑in methods like
add()
,remove()
,get()
,size()
, and more. - Internally backed by an array and resizes when capacity is exceeded.
Example usage:
javaCopyEditimport java.util.ArrayList;
ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
System.out.println(list.get(0));
System.out.println(list.size());
Key Differences at a Glance
Feature | Java Array | ArrayList |
---|---|---|
Size | Fixed at creation | Dynamic (can grow or shrink) |
Type of elements | Primitives & objects | Objects only (via generics) |
Syntax access | arr[index] | list.get(index) |
Adding/removing | Not built-in | add() and remove() methods |
Resizing performance | N/A (cannot) | May be slower due to internal array copy |
Generics | Not supported | Supported (type-safe) |
Memory layout | Contiguous block | References contiguous; actual objects separate |
Multi-dimensional | Supported (e.g. int[][] arr ) | Only single-dimensional |
Useful methods | None built-in | indexOf() , contains() , clear() |
Performance | Very fast access, low overhead | Slight overhead, resizing cost |
Null handling | Objects allow null , primitives do not | Nulls allowed in object types |
Use cases | Known fixed-size, performance-critical | Flexible, frequently modified lists |
Detailed Comparison

Size and Flexibility
Array size is fixed: int[] arr = new int[10];
. You cannot add more than 10 elements.
ArrayList can grow and shrink: new ArrayList<>()
. It resizes as elements are added or removed.
Type Support and Generics
Arrays support both primitives and objects.
ArrayList supports only object types. For primitives, you must use wrapper classes like Integer
, Double
, etc.
Generics are not supported by arrays, but ArrayList supports them fully, providing type safety at compile time (source)
Performance
Arrays provide fast, direct access (O(1)
) and low overhead.
ArrayList provides similar access speed but may occasionally slow down due to resizing. Internally, when capacity is exceeded, a new array is created and elements are copied.
Built-in Functionality
Arrays are minimal. No built-in methods beyond length
.
ArrayList offers a wide range of methods: add()
, remove()
, indexOf()
, contains()
, clear()
, and supports iteration and Java Streams.
Memory Layout
Primitive arrays store values in a contiguous block.
Object arrays and ArrayLists store references contiguously, but the actual objects can reside anywhere on the heap.
Multi-dimensional Data
Arrays can be multi-dimensional (e.g. int[][] matrix
).
ArrayLists support only single-dimension natively, although nested ArrayLists can simulate multi-dimensionality.
Example Code Snippets
Fixed-size Array Example
javaCopyEditpublic class ArrayExample {
public static void main(String[] args) {
int[] arr = new int[3];
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
System.out.println("Length: " + arr.length);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
Dynamic ArrayList Example
javaCopyEditimport java.util.ArrayList;
public class ArrayListExample {
public static void main(String[] args) {
ArrayList<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Cherry");
System.out.println("Size: " + fruits.size());
for (String f : fruits) {
System.out.println(f);
}
fruits.remove(1);
fruits.add("Date");
System.out.println(fruits);
System.out.println("Contains Apple? " + fruits.contains("Apple"));
}
}
Primitive vs Object Types
javaCopyEditint[] primitiveArr = {1, 2, 3};
Integer[] objArr = {1, 2, 3};
ArrayList<Integer> list = new ArrayList<>();
list.add(1); // autoboxing
ArrayList Resizing Behavior
javaCopyEditArrayList<Integer> numbers = new ArrayList<>(2);
numbers.add(10);
numbers.add(20);
numbers.add(30); // triggers internal resizing
System.out.println(numbers);
When to Use Each
Use Array When:
- The size is known and fixed.
- You want to store primitive types.
- You need performance and memory efficiency.
- You require multi-dimensional data storage.
Use ArrayList When:
- The size can change dynamically.
- You are working with objects and prefer generics.
- You need built-in methods for adding, removing, and searching.
- You’re dealing with data that’s frequently modified.
Performance Considerations
- Access time for both is constant (
O(1)
). - Adding in arrays requires manual resizing; ArrayLists handle this internally.
- Removing in arrays involves shifting manually; ArrayLists do it automatically.
- Memory use is typically lower for arrays, unless you’re storing a lot of nulls in a larger capacity ArrayList.
- For performance-critical applications, arrays are often preferred. For convenience, ArrayList is superior.
Advanced Examples
Wrapping an Array as a List
javaCopyEditString[] planets = { "Mercury", "Venus", "Earth", "Mars" };
List<String> fixed = Arrays.asList(planets);
List<String> dynamic = new ArrayList<>(Arrays.asList(planets));
planets[0] = "Pluto";
System.out.println(fixed); // reflects change
System.out.println(dynamic); // independent copy
Converting ArrayList to Array
javaCopyEditArrayList<String> list = new ArrayList<>();
list.add("A");
list.add("B");
String[] arr = list.toArray(new String[list.size()]);
Summary
- Array: Fast, lightweight, fixed-size, supports primitives and objects.
- ArrayList: Dynamic, flexible, object-only, built-in methods, type-safe via generics (read more).
- Choose arrays for performance-sensitive and size-stable needs.
- Choose ArrayList for flexible, evolving collections where convenience and readability matter.
Code Comparison Side-by-Side
javaCopyEdit// Array
int[] arr = new int[3];
arr[0] = 1; arr[1] = 2; arr[2] = 3;
// ArrayList
ArrayList<Integer> al = new ArrayList<>();
al.add(1); al.add(2); al.add(3);
al.add(4);
System.out.println(al.get(2));
al.remove(Integer.valueOf(2));
System.out.println(al.contains(3));
Real‑World Use Cases
- Configuration constants → Use arrays
- Dynamic user input → Use ArrayList
- Data matrices or grids → Use multi-dimensional arrays
- Object collections with sorting/filtering → Use ArrayList with Streams
Best Practices & Tips
- Always use generics with ArrayList.
- Be cautious of autoboxing when storing primitives.
- Pre-allocate ArrayList capacity if you expect many elements.
- Use
List
as the interface type, e.g.,List<String> list = new ArrayList<>();
for better flexibility.
The Take Home – Difference Between Array and ArrayList in Java
The difference between array and ArrayList in Java lies in size management, type compatibility, flexibility, and functionality. Arrays offer simplicity and performance, ideal for fixed-size collections. ArrayLists, on the other hand, provide versatility and ease of use, ideal for dynamic and complex data operations.
By understanding their distinctions, Java developers can make smarter choices depending on the use case—whether optimizing for speed and memory or leveraging modern programming conveniences.