Introduction
In Java, ArrayList is a part of the Collection Framework and is present in the java.util package. It is a resizable array implementation of the List interface. Unlike arrays, which have a fixed size, an ArrayList can dynamically grow or shrink as elements are added or removed.
1. Key Features of ArrayList
- Dynamic Resizing – Automatically grows when elements exceed capacity and shrinks when elements are removed.
- Indexed Access – Provides fast random access using an index (similar to arrays).
- Duplicates Allowed – Stores duplicate elements as well as
nullvalues. - Maintains Insertion Order – Elements are stored in the order they are inserted.
- Non-synchronized – Not thread-safe by default, but can be synchronized using
Collections.synchronizedList(). - Implements List Interface – Supports all list operations like insertion, deletion, traversal, and searching.
- Heterogeneous Data – Technically possible (when using raw types), but not recommended. Best practice is to use generics.
2. Syntax of ArrayList in Java
To declare and initialize an ArrayList, you can use the following syntax:
// Creating an ArrayList of Integer type
ArrayList < Integer > arr = new ArrayList < Integer > ();
ArrayList<Integer>specifies that this list will store only Integer values.new ArrayList<Integer>()creates a new empty ArrayList.
👉You can also create an ArrayList with other data types using generics:
ArrayList < String > names = new ArrayList < String > (); // Stores String values
ArrayList < Double > prices = new ArrayList < Double > (); // Stores Double values
ArrayList < Character > letters = new ArrayList < >(); // Diamond operator, type inferred
Note:
- Since Java 7, you can use the diamond operator
<>to avoid repeating the type on the right-hand side:
ArrayList<Integer> numbers = new ArrayList<>(); // Type is inferred as Integer
- Generics enforce type safety, preventing accidental insertion of wrong types.
3. Declaration and Initialization
import java.util.ArrayList;
public class ArrayListExample {
public static void main(String[] args) {
// Creating an ArrayList of String type
ArrayList<String> fruits = new ArrayList<>();
// Adding elements
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Mango");
fruits.add("Orange");
System.out.println(fruits);
}
}
Output:
[Apple, Banana, Mango, Orange]
4. Common Operations on ArrayList
The ArrayList class provides many useful methods to perform operations. Let’s look at the most commonly used ones with description and examples:
4.a. Adding Elements
- The
add()method is used to insert elements into theArrayList. - You can add elements at the end or at a specific index.
ArrayList < String > fruits = new ArrayList < >();
fruits.add("Apple"); // Adds element at the end
fruits.add("Banana");
fruits.add(1, "Mango"); // Adds "Mango" at index 1
System.out.println(fruits);
Output:
[Apple, Mango, Banana]
4.b. Accessing Elements
- The
get(int index)method returns the element present at the given index. - Index starts from 0.
String fruit = fruits.get(1);
System.out.println("Element at index 1: " + fruit);
Output:
Element at index 1: Mango
4.c. Updating Elements
- The
set(int index, E element)method replaces the element at the specified index with a new value.
fruits.set(1, "Orange"); // Replaces "Mango" with "Orange"
System.out.println(fruits);
Output:
[Apple, Orange, Banana]
4.d. Removing Elements
- The
remove()method deletes elements by value or by index.
fruits.remove("Banana"); // Removes "Banana"
fruits.remove(0); // Removes element at index 0
System.out.println(fruits);
Output:
[Orange]
4.e. Checking Size
- The
size()method returns the total number of elements in the list.
System.out.println("Size: " + fruits.size());
4.f. Iterating Over ArrayList
- There are multiple ways to iterate over an
ArrayList:
// Using for-each loop
for (String f : fruits) {
System.out.println(f);
}
// Using for loop with index
for (int i = 0; i < fruits.size(); i++) {
System.out.println(fruits.get(i));
}
// Using forEach() method with lambda
fruits.forEach(System.out::println);
4.g. Checking if Element Exists
- The
contains(Object o)method returnstrueif the element exists, otherwisefalse.
if (fruits.contains("Mango")) {
System.out.println("Mango is in the list!");
}
4.h. Converting ArrayList to Array
- The
toArray()method converts anArrayListinto a normal array.
String[] arr = fruits.toArray(new String[0]);
for (String s : arr) {
System.out.println(s);
}
Example – Full Program
import java.util.ArrayList;
public class ArrayListDemo {
public static void main(String[] args) {
ArrayList<String> fruits = new ArrayList<>();
// Adding elements
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Mango");
fruits.add("Orange");
// Displaying ArrayList
System.out.println("Fruits: " + fruits);
// Accessing elements
System.out.println("Element at index 1: " + fruits.get(1));
// Updating element
fruits.set(2, "Papaya");
System.out.println("Updated Fruits: " + fruits);
// Removing element
fruits.remove("Orange");
System.out.println("After removal: " + fruits);
// Iterating
System.out.println("Iterating with for-each loop:");
for (String fruit : fruits) {
System.out.println(fruit);
}
// Size of ArrayList
System.out.println("Total Fruits: " + fruits.size());
}
}
Output:
Fruits: [Apple, Banana, Mango, Orange]
Element at index 1: Banana
Updated Fruits: [Apple, Banana, Papaya, Orange]
After removal: [Apple, Banana, Papaya]
Iterating with for-each loop:
Apple
Banana
Papaya
Total Fruits: 3
5. When to Use ArrayList in Java
ArrayList is one of the most commonly used collection classes in Java, but it is not always the best choice for every scenario. Here’s when you should use it:
5.a. When You Need Dynamic Arrays
- Unlike standard arrays in Java, the size of an
ArrayListcan grow or shrink automatically. - Use
ArrayListwhen you don’t know the number of elements in advance.
Example:
ArrayList < String > names = new ArrayList < >();
names.add("Alice");
names.add("Bob"); // size grows automatically
5.b. When You Need Fast Random Access
ArrayListprovides O(1) time complexity for accessing elements by index because it is internally backed by an array.- Ideal when your application frequently retrieves elements by index.
Example:
String name = names.get(0); // Fast access
5.c. When Insertion/Deletion is Mostly at the End
- Adding elements to the end of the list is very efficient (
O(1)amortized). - Removing or inserting elements in the middle or beginning is slower (
O(n)), so avoid if frequent mid-list modifications are required.
Example:
names.add("Charlie"); // Efficient
names.remove(names.size() - 1); // Efficient
5.d. When You Want to Maintain Order
ArrayListmaintains insertion order, which means elements are stored in the order they were added.- Useful when order matters in your application.
Example:
ArrayList < String > tasks = new ArrayList < >();
tasks.add("Design");
tasks.add("Development");
tasks.add("Testing");
System.out.println(tasks); // [Design, Development, Testing]
5.e. When You Need Null or Duplicate Values
ArrayListallows duplicate elements and null values, unlikeSetimplementations.
Example:
ArrayList < String > list = new ArrayList < >();
list.add(null);
list.add("Apple");
list.add("Apple"); // Duplicates allowed
✅ When Not to Use ArrayList
- Frequent insertions/deletions in the middle or start → Use
LinkedListinstead. - Thread-safe operations required → Use
CopyOnWriteArrayListorCollections.synchronizedList(). - Primitive types → Consider using arrays or
IntStream/long[]for performance, asArrayList<Integer>introduces boxing/unboxing overhead.
In short:
Use
ArrayListwhen you need a dynamic, ordered, and index-based collection where additions/removals are mostly at the end, and you may allow duplicates and nulls.
6. ArrayList Complexity
ArrayList is backed by a dynamic array, so operations are indexed-based.
| Operation | Complexity | Notes |
|---|---|---|
| Access (get/set) | O(1) | Direct index access. |
| Insert at end | O(1) amortized | May require resizing (O(n) occasionally). |
| Insert at index | O(n) | Shifts elements to the right. |
| Remove by index | O(n) | Shifts elements to the left. |
| Remove by value | O(n) | Needs traversal. |
| Search (contains, indexOf) | O(n) | Linear search. |
| Iteration | O(n) | Sequential traversal. |
👉 For a detailed guide on initializing an ArrayList using List.of() and Arrays.asList(), check out How to Initialize ArrayList in Java
🎯Conclusion
The ArrayList in Java is a powerful and flexible alternative to arrays, especially when you need dynamic resizing, indexed access, and frequent insertions/deletions. However, if thread-safety is required, you should consider using Collections.synchronizedList() or CopyOnWriteArrayList.