Java ArrayList: Add, Remove, Loop, and Sort

ArrayList is the most-used collection in Java: a list that grows and shrinks automatically as you add and remove items. This tutorial covers everything you need day to day, including creating, reading, changing, and looping over an ArrayList, and how to sort an ArrayList in any order.

What is an ArrayList in Java?

An ArrayList is a resizable list. Behind the scenes it stores items in a normal array, and when that array fills up, it quietly creates a bigger one and copies everything across. You get the speed of an array without having to choose a size up front. It's part of the Java Collections Framework and implements the List interface.

ArrayArrayList
SizeFixed when createdGrows and shrinks automatically
Holds primitives (int)?✔ Yes✘ No, uses Integer (auto-converted)
Syntaxarr[0], arr.lengthlist.get(0), list.size()
Built-in helpersFewadd, remove, contains, sort, …

How do you create and use an ArrayList?

import java.util.ArrayList;
import java.util.List;

List<String> tasks = new ArrayList<>();   // empty list of Strings

tasks.add("Write report");                // add to the end
tasks.add("Email Sam");
tasks.add(0, "Coffee");                   // insert at index 0

System.out.println(tasks);                // [Coffee, Write report, Email Sam]
System.out.println(tasks.get(1));         // Write report
System.out.println(tasks.size());         // 3

tasks.set(2, "Call Sam");                 // replace item at index 2
tasks.remove("Coffee");                   // remove by value
System.out.println(tasks.contains("Call Sam"));   // true
System.out.println(tasks);
[Coffee, Write report, Email Sam]
Write report
3
true
[Write report, Call Sam]
  • List<String> — the variable type is the List interface; <String> means it only holds Strings.
  • new ArrayList<>() — the empty <> ("diamond") lets Java infer String.
  • Indexes start at 0. get(3) on a 3-item list throws IndexOutOfBoundsException.

Most-used ArrayList methods

MethodWhat it does
add(x) / add(i, x)Add to the end / insert at index i
get(i)Read the item at index i
set(i, x)Replace the item at index i
remove(i) / remove(x)Remove by index / remove first matching value
size(), isEmpty()How many items / are there none?
contains(x), indexOf(x)Is it there? / where is it (−1 if missing)
removeIf(cond)Remove every item matching a condition
getFirst(), getLast(), reversed()Java 21+ shortcuts for the ends and a reversed view
clear()Remove everything

How do you loop through an ArrayList?

List<Integer> scores = new ArrayList<>(List.of(70, 85, 92));

for (int score : scores) {                       // 1. for-each: simplest
    System.out.println(score);
}

for (int i = 0; i < scores.size(); i++) {         // 2. index loop: when you need i
    System.out.println(i + ": " + scores.get(i));
}

scores.forEach(s -> System.out.println(s));       // 3. forEach with a lambda

Don't remove items inside a for-each loop. It throws ConcurrentModificationException. Use removeIf instead:

for (int s : scores) {
    if (s < 80) scores.remove(Integer.valueOf(s));   // ✘ ConcurrentModificationException
}

scores.removeIf(s -> s < 80);                      // ✔ safe and shorter

Why does remove(1) on a list of numbers remove the wrong thing?

remove has two versions: by index and by value. With a List<Integer>, remove(1) means "remove index 1". To remove the number 1, write remove(Integer.valueOf(1)).

How do you sort an ArrayList in Java?

Since Java 8, the simplest way is list.sort(...), passing a Comparator that says how to compare two items. Collections.sort(list) still works and does the same thing. Pick a sort order to see the result for ["diana", "Ben", "carlos", "asha"]:

Sort an ArrayList of names

Natural order

Alphabetical for strings, smallest-first for numbers. Watch out: every uppercase letter sorts before every lowercase one, so "Ben" comes before "asha".

names.sort(null);   // or Collections.sort(names)
// [Ben, asha, carlos, diana]

Descending

Reverse of natural order.

names.sort(Comparator.reverseOrder());
// [diana, carlos, asha, Ben]

Ignore case

Alphabetical the way people expect, ignoring upper/lower case. Usually what you want for names.

names.sort(String.CASE_INSENSITIVE_ORDER);
// [asha, Ben, carlos, diana]

By length

Shortest first, using a key extractor. If two items tie, they keep their original order, because Java's list sort is stable.

names.sort(Comparator.comparing(String::length));
// [Ben, asha, diana, carlos]
Every option sorts the same list in place. Pass null for natural order, or a Comparator for anything else.

Sorting numbers ascending and descending

List<Integer> prices = new ArrayList<>(List.of(30, 5, 18, 42));

prices.sort(null);                           // ascending
System.out.println(prices);

prices.sort(Comparator.reverseOrder());      // descending
System.out.println(prices);
[5, 18, 30, 42]
[42, 30, 18, 5]

Sorting a list of objects by a field

This is what you'll do most in real projects. Comparator.comparing takes a "key" to sort by:

record Product(String name, double price, int rating) { }

List<Product> products = new ArrayList<>(List.of(
    new Product("Lamp", 25.0, 4),
    new Product("Desk", 120.0, 5),
    new Product("Chair", 25.0, 5)
));

// Cheapest first
products.sort(Comparator.comparing(Product::price));

// Most expensive first
products.sort(Comparator.comparing(Product::price).reversed());

// Cheapest first, then best-rated among equal prices
products.sort(Comparator.comparing(Product::price)
                        .thenComparing(Product::rating, Comparator.reverseOrder()));

products.forEach(p -> System.out.println(p.name() + " $" + p.price() + " ★" + p.rating()));
Chair $25.0 ★5
Lamp $25.0 ★4
Desk $120.0 ★5
  • Product::price — a method reference meaning "use each product's price as the sort key".
  • .reversed() — flips the whole comparator.
  • .thenComparing(...) — the tie-breaker when the first key is equal.

Want a sorted copy instead? list.stream().sorted(comparator).toList() returns a new sorted list and leaves the original unchanged.

Making your own class sortable with Comparable

If a class has one obvious "natural" order, implement Comparable. Then sort(null) just works:

record Version(int major, int minor) implements Comparable<Version> {
    @Override
    public int compareTo(Version other) {
        return Comparator.comparingInt(Version::major)
                         .thenComparingInt(Version::minor)
                         .compare(this, other);
    }
}

List<Version> versions = new ArrayList<>(List.of(new Version(2, 1), new Version(1, 9), new Version(2, 0)));
versions.sort(null);
System.out.println(versions);
[Version[major=1, minor=9], Version[major=2, minor=0], Version[major=2, minor=1]]

When is ArrayList fast or slow?

  • Fast: get(i), set(i, x), and adding to the end.
  • Slower on big lists: inserting or removing near the start (everything after shifts along), and contains/indexOf (checks items one by one).
  • Need fast "is it there?" checks? Use a HashSet. Need a queue? Use ArrayDeque. See which collection to use.

Quick recap

  • List<T> list = new ArrayList<>() creates a resizable list.
  • add, get, set, remove, size, and contains cover most needs.
  • Use removeIf, not remove-inside-for-each.
  • Sort with list.sort(null) or a Comparator: reverseOrder(), comparing(...), .reversed(), .thenComparing(...).

What's next?

An ArrayList isn't safe to change from several threads at once. Learn the fixes in thread-safe lists in Java, or review the Collections Framework.

Frequently Asked Questions

How do I sort an ArrayList in Java?

Call list.sort(null) or Collections.sort(list) to sort in natural order: numbers ascending, strings alphabetically. For a custom order, pass a Comparator, for example list.sort(Comparator.reverseOrder()) for descending, or list.sort(Comparator.comparing(Person::age)) to sort objects by a field.

How do I sort an ArrayList in descending order?

Use list.sort(Comparator.reverseOrder()) for simple values like numbers and strings. For objects, add .reversed() to your comparator, for example list.sort(Comparator.comparing(Product::price).reversed()).

What is the difference between an array and an ArrayList?

An array has a fixed size set when you create it, and it can hold primitives like int. An ArrayList grows and shrinks automatically, has helpful methods like add, remove, and contains, but only holds objects, so ints are stored as Integer.

Why do I get ConcurrentModificationException?

You removed or added items while looping over the same list with a for-each loop. The loop's iterator detects the change and stops. Use list.removeIf(condition) or an explicit Iterator's remove() method instead.

Is ArrayList thread-safe?

No. If several threads modify the same ArrayList at once, you can get corrupted data or exceptions. Use Collections.synchronizedList(...) or CopyOnWriteArrayList, explained in our guide to thread-safe lists in Java.

What is the initial capacity of an ArrayList?

An ArrayList created with new ArrayList<>() starts with an empty internal array and grows to room for 10 elements on the first add. When full, it grows by about 50%. If you know the size in advance, new ArrayList<>(1000) avoids repeated resizing.