← Back to Core Java Course | Chapter 11: Collections | Lesson 17 of 17

Java List Sorting

Sorting with Collections.sort()

The static method Collections.sort(list) sorts a List in place using each element's natural ordering, which requires the elements to implement Comparable. It has been part of Java since the original Collections Framework and is still common in code written before Java 8.

Example: Sorting with Collections.sort()

java
import java.util.Collections;
import java.util.ArrayList;
public class Main {
	public static void main(String[] args) {
		ArrayList<Integer> nums = new ArrayList<>(java.util.List.of(3, 1, 2));
		Collections.sort(nums); // natural ordering, requires Comparable
		System.out.println(nums);
	}
}

Sorting with List.sort()

Since Java 8, every List has its own instance method list.sort(comparator), which is often preferred over Collections.sort() because it reads more naturally and lets you pass null to fall back to natural ordering. Both methods sort the list in place rather than returning a new sorted list.

Example: Sorting with List.sort()

java
import java.util.ArrayList;
public class Main {
	public static void main(String[] args) {
		ArrayList<Integer> nums = new ArrayList<>(java.util.List.of(3, 1, 2));
		nums.sort(null); // null falls back to natural ordering
		System.out.println(nums);
	}
}

Natural Ordering via Comparable

A class defines its own default sort order by implementing Comparable<T> and its compareTo() method, returning negative, zero, or positive to indicate less-than, equal-to, or greater-than. Built-in types like String and Integer already implement Comparable, which is why lists of them sort correctly with no extra setup.

Example: Natural Ordering via Comparable

java
class Person implements Comparable<Person> {
	int age;
	Person(int age) { this.age = age; }
	public int compareTo(Person other) {
		return this.age - other.age;
	}
}
public class Main {
	public static void main(String[] args) {
		java.util.ArrayList<Person> people = new java.util.ArrayList<>();
		people.add(new Person(30));
		people.add(new Person(20));
		java.util.Collections.sort(people);
		System.out.println(people.get(0).age);
	}
}

Custom Ordering via Comparator Lambda

When you need a sort order different from the natural one, or you're sorting a class you can't modify, pass a Comparator instead — a lambda like list.sort((a, b) -> a.getAge() - b.getAge()) sorts by a different field entirely. Unlike Comparable, a class can have many different comparators without changing its own code.

Example: Custom Ordering via Comparator Lambda

java
import java.util.ArrayList;
class Person {
	int age;
	Person(int age) { this.age = age; }
}
public class Main {
	public static void main(String[] args) {
		ArrayList<Person> people = new ArrayList<>();
		people.add(new Person(30));
		people.add(new Person(20));
		people.sort((a, b) -> a.age - b.age);
		System.out.println(people.get(0).age);
	}
}

Sorting by Multiple Keys

The Comparator.comparing() and .thenComparing() methods let you build a multi-level sort, for example sorting people by last name and using first name only as a tiebreaker when last names match. This reads clearly left to right and avoids writing a long manual if/else chain inside a compareTo() or lambda body.

Example: Sorting by Multiple Keys

java
import java.util.ArrayList;
import java.util.Comparator;
class Person {
	String lastName, firstName;
	Person(String lastName, String firstName) {
		this.lastName = lastName;
		this.firstName = firstName;
	}
}
public class Main {
	public static void main(String[] args) {
		ArrayList<Person> people = new ArrayList<>();
		people.add(new Person("Smith", "Bob"));
		people.add(new Person("Smith", "Alice"));
		people.sort(Comparator.comparing((Person p) -> p.lastName)
				.thenComparing(p -> p.firstName));
		System.out.println(people.get(0).firstName);
	}
}

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.