In the previous blog, we learned about arrays in Java.
But arrays have one limitation: their size is fixed.
For example:
int[] numbers = new int[3];
This array can store only 3 values. We cannot directly increase its size later.
This is where ArrayList is useful.
An ArrayList allows us to store multiple values and dynamically grow or shrink the list when needed.
ArrayList is a class in Java that is used to store a collection of elements.
Unlike an array, an ArrayList can change its size during program execution.
For example:
ArrayList<Integer> numbers = new ArrayList<>();
We can add values:
numbers.add(10);
numbers.add(20);
numbers.add(30);
Now the list contains:
[10, 20, 30]
We can add more values whenever needed.
Before using ArrayList, we need to import it:
import java.util.ArrayList;
The basic syntax is:
ArrayList<DataType> listName = new ArrayList<>();
For example:
ArrayList<Integer> numbers = new ArrayList<>();
Here:
ArrayList is the class.Integer is the type of elements stored in the list.numbers is the variable name.new ArrayList<>() creates the ArrayList.We use the add() method to add elements.
ArrayList<String> names = new ArrayList<>();
names.add("Ravi");
names.add("Anu");
names.add("Kiran");
System.out.println(names);
Output:
[Ravi, Anu, Kiran]
We can keep adding elements without specifying the size beforehand.
ArrayList uses indexes just like arrays.
The index starts from 0.
Index: 0 1 2
↓ ↓ ↓
Ravi Anu Kiran
We use the get() method to access an element.
System.out.println(names.get(0));
Output:
Ravi
We can change an existing element using the set() method.
ArrayList<String> names = new ArrayList<>();
names.add("Ravi");
names.add("Anu");
names.add("Kiran");
names.set(1, "Priya");
System.out.println(names);
Output:
[Ravi, Priya, Kiran]
We can remove an element using the remove() method.
ArrayList<String> names = new ArrayList<>();
names.add("Ravi");
names.add("Anu");
names.add("Kiran");
names.remove(1);
System.out.println(names);
Output:
[Ravi, Kiran]
The element at index 1 was removed.
For arrays, we use:
array.length
For an ArrayList, we use the size() method:
names.size()
Example:
ArrayList<String> names = new ArrayList<>();
names.add("Ravi");
names.add("Anu");
names.add("Kiran");
System.out.println(names.size());
Output:
3
We can use contains() to check whether an element is present.
ArrayList<String> names = new ArrayList<>();
names.add("Ravi");
names.add("Anu");
names.add("Kiran");
System.out.println(names.contains("Anu"));
Output:
true
If the element is not present:
System.out.println(names.contains("Rahul"));
Output:
false
We can use a regular for loop to access each element.
ArrayList<String> names = new ArrayList<>();
names.add("Ravi");
names.add("Anu");
names.add("Kiran");
for (int i = 0; i < names.size(); i++) {
System.out.println(names.get(i));
}
Output:
Ravi
Anu
Kiran
We can also use a for-each loop to access each element of an ArrayList.
ArrayList<String> names = new ArrayList<>();
names.add("Ravi");
names.add("Anu");
names.add("Kiran");
for (String name : names) {
System.out.println(name);
}
Output:
Ravi
Anu
Kiran
The for-each loop is useful when we simply want to read or process every element without needing the index.
| Array | ArrayList |
|---|---|
| Fixed size | Size can change |
Uses length |
Uses size() |
Access using array[index] |
Access using get(index) |
| Add using assignment | Add using add() |
Change using array[index] = value |
Change using set() |
| Remove is not directly available | Can remove using remove() |
Just like arrays can have multiple dimensions, we can also create an ArrayList containing other ArrayList objects.
This can be useful when we want to store data in rows and columns while keeping the size of the lists flexible.
For example:
ArrayList<ArrayList<Integer>> numbers = new ArrayList<>();
Here, the outer ArrayList stores multiple inner ArrayList objects.
Let's create two rows:
ArrayList<ArrayList<Integer>> numbers = new ArrayList<>();
ArrayList<Integer> row1 = new ArrayList<>();
row1.add(10);
row1.add(20);
row1.add(30);
ArrayList<Integer> row2 = new ArrayList<>();
row2.add(40);
row2.add(50);
row2.add(60);
numbers.add(row1);
numbers.add(row2);
System.out.println(numbers);
Output:
[[10, 20, 30], [40, 50, 60]]
We can think of it like this:
Row 0 → [10, 20, 30]
Row 1 → [40, 50, 60]
We can use two get() methods to access an element:
System.out.println(numbers.get(0).get(1));
Output:
20
Here:
numbers.get(0)
gets the first row.
Then:
.get(1)
gets the element at index 1 from that row.
We can use nested loops to access all the elements.
for (int i = 0; i < numbers.size(); i++) {
for (int j = 0; j < numbers.get(i).size(); j++) {
System.out.print(numbers.get(i).get(j) + " ");
}
System.out.println();
}
Output:
10 20 30
40 50 60
We can also use nested for-each loops:
for (ArrayList<Integer> row : numbers) {
for (Integer value : row) {
System.out.print(value + " ");
}
System.out.println();
}
Output:
10 20 30
40 50 60
The outer loop goes through each row, and the inner loop goes through each element in that row.
| 2D Array | 2D ArrayList |
|---|---|
| Fixed size | Size can grow or shrink |
Uses array[row][column] |
Uses get(row).get(column) |
Uses length |
Uses size() |
| Stores elements of the same type | Stores elements based on the ArrayList type |
| Useful for fixed table-like data | Useful when rows or columns may change |
ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(10);
numbers.add(20);
numbers.add(30);
numbers.set(1, 50);
System.out.println(numbers);
ArrayList<String> names = new ArrayList<>();
names.add("Ravi");
names.add("Anu");
System.out.println(names.length);
ArrayList<String> names = new ArrayList<>();
names.add("Ravi");
names.add("Anu");
names.add("Kiran");
names.remove(0);
names.set(1, "Priya");
System.out.println(names);