Java ArrayList
The ArrayList class is the most commonly used collection
in Java. It's a resizable array implementation of the List interface,
offering fast random access and dynamic sizing.
Array vs ArrayList
Unlike fixed-size arrays, ArrayList grows and shrinks automatically:
| Feature | Array | ArrayList |
|---|---|---|
| Size | Fixed at creation | Dynamic (grows/shrinks) |
| Type | Primitives and Objects | Objects only (use wrappers) |
| Methods | Only .length |
add(), remove(), contains(), etc. |
| Performance | Slightly faster | Slight overhead for flexibility |
Creating an ArrayList
import java.util.ArrayList;
import java.util.List;
// Standard way - specify type in angle brackets (generics)
ArrayList<String> cars = new ArrayList<String>();
// Diamond operator (Java 7+) - type inferred
ArrayList<String> cars = new ArrayList<>();
// Best practice: program to interface
List<String> cars = new ArrayList<>();
// With initial capacity (optimization)
List<String> bigList = new ArrayList<>(1000);
Essential Operations
| Operation | Method | Time Complexity |
|---|---|---|
| Add at end | add(element) |
O(1) amortized |
| Add at index | add(index, element) |
O(n) |
| Get by index | get(index) |
O(1) |
| Set at index | set(index, element) |
O(1) |
| Remove by index | remove(index) |
O(n) |
| Search | contains(element) |
O(n) |
| Size | size() |
O(1) |
Output
Click Run to execute your code
Iterating Through ArrayList
List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Cherry");
// 1. For-each loop (preferred for reading)
for (String fruit : fruits) {
System.out.println(fruit);
}
// 2. Traditional for loop (when you need index)
for (int i = 0; i < fruits.size(); i++) {
System.out.println(i + ": " + fruits.get(i));
}
// 3. Iterator (when removing during iteration)
Iterator<String> it = fruits.iterator();
while (it.hasNext()) {
if (it.next().startsWith("B")) {
it.remove(); // Safe removal
}
}
// 4. Java 8+ forEach with lambda
fruits.forEach(fruit -> System.out.println(fruit));
// 5. Java 8+ Stream API
fruits.stream()
.filter(f -> f.length() > 5)
.forEach(System.out::println);
More Useful Methods
List<Integer> numbers = new ArrayList<>();
numbers.addAll(Arrays.asList(5, 2, 8, 1, 9));
// Sorting
Collections.sort(numbers); // [1, 2, 5, 8, 9]
Collections.reverse(numbers); // [9, 8, 5, 2, 1]
// Searching (list must be sorted for binarySearch)
Collections.sort(numbers);
int idx = Collections.binarySearch(numbers, 5);
// Min/Max
int min = Collections.min(numbers); // 1
int max = Collections.max(numbers); // 9
// Sublist (view, not copy)
List<Integer> sub = numbers.subList(1, 4);
// Convert to array
Integer[] arr = numbers.toArray(new Integer[0]);
// Check if empty
boolean empty = numbers.isEmpty();
Wrapper Classes for Primitives
ArrayList can only store objects. For primitive types, use wrapper classes:
| Primitive | Wrapper Class |
|---|---|
int | Integer |
double | Double |
boolean | Boolean |
char | Character |
long | Long |
// Autoboxing: Java automatically converts
ArrayList<Integer> nums = new ArrayList<>();
nums.add(42); // int autoboxed to Integer
int n = nums.get(0); // Integer unboxed to int
When to Use ArrayList:
- You need fast random access by index - O(1)
- You mostly add elements at the end
- You rarely insert/delete in the middle
- You don't know the size in advance
Summary
- ArrayList is a dynamic array with O(1) random access
- Use
List<Type>interface for flexibility - Best for: reading by index, appending elements
- Avoid for: frequent insertions/deletions in middle
- Use wrapper classes for primitive types
Enjoying these tutorials?