Java course menu
Java ArrayList: Adding, Removing, Searching, Sorting and Iterating
Learn Java ArrayList: creating lists, add, get, set and remove, size and contains, indexOf, looping, removeIf and the ConcurrentModificationException, sorting with sort and Comparator, converting between arrays and lists, and ArrayList vs LinkedList.
On this page
ArrayList is a resizable array, and the list you will use most in Java. It keeps elements in order, allows duplicates, gives fast access by index, and grows automatically as you add elements.
Creating a list and adding elements#
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> cart = new ArrayList<>();
cart.add("Milk");
cart.add("Bread");
cart.add("Eggs");
cart.add(1, "Butter"); // insert at index 1
System.out.println(cart);
System.out.println(cart.size() + " items, first: " + cart.get(0));
}
}[Milk, Butter, Bread, Eggs]
4 items, first: MilkPrinting a list shows its elements in square brackets, because ArrayList overrides toString.
Reading, changing and searching#
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> fruits = new ArrayList<>(List.of("apple", "banana", "cherry", "banana"));
fruits.set(0, "avocado"); // replace by index
System.out.println(fruits);
System.out.println(fruits.contains("cherry") + " " + fruits.indexOf("banana") + " " + fruits.lastIndexOf("banana"));
System.out.println(fruits.indexOf("kiwi")); // -1 when not found
System.out.println(fruits.isEmpty());
}
}[avocado, banana, cherry, banana]
true 1 3
-1
falseget(i) and set(i, x) throw IndexOutOfBoundsException for invalid indexes.
Removing elements#
remove has two overloads: by index and by value:
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> names = new ArrayList<>(List.of("Asha", "Ravi", "Meera", "John"));
names.remove(0); // by index
names.remove("Meera"); // by value (the first match)
System.out.println(names);
List<Integer> nums = new ArrayList<>(List.of(10, 20, 30, 1));
nums.remove(1); // index 1, removes 20
nums.remove(Integer.valueOf(1)); // the value 1
System.out.println(nums);
nums.clear();
System.out.println(nums.isEmpty());
}
}[Ravi, John]
[10, 30]
trueWith a List<Integer>, remove(1) means index 1. To remove the value 1, pass an Integer object.
Iterating#
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Double> prices = new ArrayList<>(List.of(120.0, 45.5, 300.0));
double total = 0;
for (double p : prices) {
total += p;
}
System.out.println("Total: " + total);
for (int i = 0; i < prices.size(); i++) {
prices.set(i, prices.get(i) * 1.18); // add 18% tax in place
}
prices.forEach(p -> System.out.printf("%.2f ", p));
System.out.println();
}
}Total: 465.5
141.60 53.69 354.00 Removing while iterating#
Removing elements inside a for-each loop throws ConcurrentModificationException. Use removeIf, which does it safely in one call:
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> nums = new ArrayList<>(List.of(5, -2, 8, -7, 3, 0, -1));
try {
for (Integer n : nums) {
if (n < 0) nums.remove(n);
}
} catch (java.util.ConcurrentModificationException e) {
System.out.println("Cannot remove inside a for-each loop");
}
List<Integer> fresh = new ArrayList<>(List.of(5, -2, 8, -7, 3, 0, -1));
fresh.removeIf(n -> n < 0);
System.out.println(fresh);
}
}Cannot remove inside a for-each loop
[5, 8, 3, 0]n -> n < 0 is a lambda (see Lambdas). An explicit Iterator with it.remove() also works.
Sorting#
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> names = new ArrayList<>(List.of("Ravi", "Asha", "Meera", "Jo"));
names.sort(null); // natural (alphabetical) order
System.out.println(names);
names.sort(Comparator.comparing(String::length)); // by length
System.out.println(names);
names.sort(Comparator.reverseOrder());
System.out.println(names);
}
}[Asha, Jo, Meera, Ravi]
[Jo, Asha, Ravi, Meera]
[Ravi, Meera, Jo, Asha]Collections.sort(list) does the same as list.sort(null). Sorting objects by your own rules is covered in Comparable, Comparator and Sorting.
Converting between arrays and lists#
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
String[] array = {"a", "b", "c"};
List<String> list = new ArrayList<>(Arrays.asList(array)); // array -> modifiable list
list.add("d");
String[] back = list.toArray(new String[0]); // list -> array
System.out.println(list + " " + back.length);
}
}[a, b, c, d] 4How ArrayList works, and ArrayList vs LinkedList#
An ArrayList stores elements in an internal array with spare capacity. Adding at the end is fast (amortized O(1)); when the array is full, it allocates a larger one and copies the elements. Access by index is O(1). Inserting or removing near the front is O(n), because later elements shift.
LinkedList stores elements in linked nodes: it is fast at adding and removing at the ends, but get(i) is O(n), and it uses more memory. In practice ArrayList is faster for almost everything; for a queue or stack, use ArrayDeque.
Common mistakes#
Practice#
Practice exercise
From List.of(4, 9, 4, 1, 9, 9, 7), build a new ArrayList that keeps only the first occurrence of each value, in order, and print it with its size.
Show solution
import java.util.ArrayList;
import java.util.List;
public class Dedupe {
public static void main(String[] args) {
List<Integer> data = List.of(4, 9, 4, 1, 9, 9, 7);
List<Integer> unique = new ArrayList<>();
for (int x : data) {
if (!unique.contains(x)) {
unique.add(x);
}
}
System.out.println(unique + " " + unique.size());
}
}[4, 9, 1, 7] 4contains is O(n), so this is O(n²) for large lists. new ArrayList<>(new LinkedHashSet<>(data)) does the same in O(n).
Key takeaway#
Finished this lesson?