Java Collections.sort Method
Last modified: April 20, 2025
The Collections.sort
method is a utility method in Java's
java.util.Collections
class. It provides functionality to sort
elements in a List. The method comes in two variants: one that sorts according
to natural ordering and one that uses a Comparator.
Sorting is a fundamental operation in programming. The Collections.sort method offers efficient sorting algorithms for Lists. It uses a modified mergesort algorithm that offers n log(n) performance.
Collections.sort Overview
The Collections.sort method sorts the specified list into ascending order. The elements must implement the Comparable interface for natural ordering. Alternatively, you can provide a Comparator for custom ordering.
The sort is stable, meaning equal elements won't be reordered. The method operates in-place, modifying the original list. For immutable lists, it throws an UnsupportedOperationException.
Basic Sorting with Collections.sort
This example demonstrates the simplest use of Collections.sort. We create a List of Strings and sort them in natural order. Strings implement Comparable, so no additional configuration is needed.
package com.zetcode; import java.util.Arrays; import java.util.Collections; import java.util.List; public class BasicSortExample { public static void main(String[] args) { List<String> names = Arrays.asList( "John", "Adam", "Jane", "Peter", "Mary" ); System.out.println("Before sorting: " + names); Collections.sort(names); System.out.println("After sorting: " + names); } }
This code creates a List of names and sorts them alphabetically. The output shows the list before and after sorting. The sort is case-sensitive as it uses String's natural ordering.
The Collections.sort method modifies the original list. If you need to preserve the original order, create a copy before sorting.
Sorting Custom Objects
To sort custom objects in Java, you can either implement the
Comparable
interface for natural ordering or provide a custom
Comparator
for specific sorting logic. This example demonstrates
the Person
record implementing Comparable
to define a
natural order based on the name
field.
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; record Person(String name, int age) implements Comparable<Person> { @Override public int compareTo(Person other) { return this.name.compareTo(other.name); } } public class CustomObjectSort { public static void main(String[] args) { List<Person> people = new ArrayList<>(); people.add(new Person("John", 25)); people.add(new Person("Adam", 30)); people.add(new Person("Jane", 22)); System.out.println("Before sorting: " + people); Collections.sort(people); System.out.println("After sorting: " + people); } }
The Person
record overrides the compareTo
method,
delegating to String
's compareTo
method to order names
alphabetically. The Collections.sort
method uses this natural
ordering to arrange the Person
objects in ascending order by name.
The output displays the list sorted alphabetically by name, as defined by the
natural ordering. Implementing the Comparable
interface is a clear
and efficient approach when objects have an inherent or "default" sorting order,
making the code easier to understand and maintain.
Sorting with Comparator
When you can't modify a class or need different sorting orders, use a
Comparator
. This example shows how to sort Persons by age using a
Comparator.
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; record Person(String name, int age) {} public class ComparatorSort { public static void main(String[] args) { List<Person> people = new ArrayList<>(); people.add(new Person("John", 25)); people.add(new Person("Adam", 30)); people.add(new Person("Jane", 22)); System.out.println("Original order: " + people); // Sort by age using Comparator Collections.sort(people, Comparator.comparingInt(Person::age)); System.out.println("Sorted by age: " + people); } }
This example uses a comparator to sort by age, created with the method reference
Comparator.comparingInt(Person::age)
. Unlike an anonymous
implementation, this approach leverages modern Java functional programming for
concise and readable code. By referencing the age
field directly,
the comparison is streamlined and avoids manual implementation of the
compare
method.
The output displays the list sorted by age in ascending order. This demonstrates the flexibility of comparators, which are particularly useful for customizing sorting logic, including handling multiple criteria or dynamic ordering.
Lambda Expressions for Sorting
Lambda expressions simplify Comparator
creation. This example shows
how to use lambdas with Collections.sor
for concise code.
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; record Person(String name, int age) {} public class LambdaSort { public static void main(String[] args) { List<Person> people = new ArrayList<>(); people.add(new Person("John", 25)); people.add(new Person("Adam", 30)); people.add(new Person("Jane", 22)); System.out.println("Original order: " + people); // Sort by name using lambda Collections.sort(people, Comparator.comparing(Person::name)); System.out.println("Sorted by name: " + people); // Sort by age using lambda Collections.sort(people, Comparator.comparingInt(Person::age)); System.out.println("Sorted by age: " + people); } }
Lambda expressions make Comparator
code much cleaner. The first
sort uses a lambda to compare names. The second sort compares ages, both in one
line each.
The output demonstrates both sorting orders. Lambdas are especially useful when you need multiple sorting criteria in different parts of your application.
Reverse Order Sorting
Collections.sort
can sort in reverse order using
Comparator.reverseOrder
or
Collections.reverseOrder
. This example shows both approaches.
package com.zetcode; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; public class ReverseSort { public static void main(String[] args) { List<String> names = Arrays.asList( "John", "Adam", "Jane", "Peter", "Mary" ); System.out.println("Original order: " + names); // Natural order sort Collections.sort(names); System.out.println("Natural order: " + names); // Reverse order using reverseOrder() Collections.sort(names, Collections.reverseOrder()); System.out.println("Reverse order: " + names); // Alternative reverse sort names.sort(Comparator.reverseOrder()); System.out.println("Alternative reverse: " + names); } }
This example first sorts names in natural order, then reverses the order.
Collections.reverseOrder
returns a Comparator
that
reverses natural ordering. The alternative uses List's sort method directly.
The output shows each sorting step. Reverse sorting is useful for displaying data in descending order, like showing highest scores first.
Sorting with Multiple Criteria
For complex sorting with multiple fields, use Comparator chaining. This example sorts Persons by name then age using thenComparing.
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; record Person(String name, int age) { } public class MultiCriteriaSort { public static void main(String[] args) { List<Person> people = new ArrayList<>(); people.add(new Person("John", 25)); people.add(new Person("Adam", 30)); people.add(new Person("Jane", 22)); people.add(new Person("Adam", 25)); System.out.println("Original order: " + people); // Sort by name then age Collections.sort(people, Comparator .comparing(Person::name) .thenComparingInt(Person::age) ); System.out.println("Sorted by name then age: " + people); } }
This example uses Java 8's Comparator.comparing and thenComparing methods. First, it sorts by name, then by age for people with the same name. The method references make the code very readable.
The output shows the list sorted primarily by name and secondarily by age. This technique is essential when dealing with complex sorting requirements.
Case-Insensitive Sorting
For case-insensitive string sorting, use String.CASE_INSENSITIVE_ORDER or a custom Comparator. This example demonstrates both approaches.
package com.zetcode; import java.util.Arrays; import java.util.Collections; import java.util.List; public class CaseInsensitiveSort { public static void main(String[] args) { List<String> words = Arrays.asList( "apple", "Orange", "banana", "PEAR", "Grape" ); System.out.println("Original order: " + words); // Case-sensitive sort (natural order) Collections.sort(words); System.out.println("Case-sensitive sort: " + words); // Case-insensitive sort using String.CASE_INSENSITIVE_ORDER Collections.sort(words, String.CASE_INSENSITIVE_ORDER); System.out.println("Case-insensitive sort: " + words); // Alternative using lambda Collections.sort(words, String::compareToIgnoreCase); System.out.println("Lambda case-insensitive: " + words); } }
The example first shows case-sensitive sorting where uppercase letters sort before lowercase. Then it demonstrates case-insensitive sorting using both String's built-in Comparator and a lambda with compareToIgnoreCase.
The output clearly shows the difference between case-sensitive and insensitive sorting. Case-insensitive sorting is often what users expect in applications.
Source
Java Collections.sort Documentation
In this article, we've explored Java's Collections.sort method in depth. We've covered basic sorting, custom objects, Comparators, lambdas, reverse sorting, multi-criteria sorting, and case sensitivity. Mastering these techniques is essential for effective Java development.
Author
List all Java tutorials.