How to sort a List/ArrayList?

Learn how to sort a list/arraylist? with practical examples, diagrams, and best practices. Covers java, list, sorting development techniques with visual explanations.

How to Sort a List or ArrayList in Java

Hero image for How to sort a List/ArrayList?

Learn the various methods to sort a List or ArrayList in Java, from natural ordering to custom comparators, ensuring your data is always organized.

Sorting data is a fundamental operation in programming, and Java provides robust mechanisms to sort collections like List and ArrayList. Whether you need to sort primitive types, custom objects, or apply complex sorting logic, Java's Collections Framework offers flexible solutions. This article will guide you through the most common and effective ways to sort your lists.

Understanding Natural Ordering and Custom Sorting

Before diving into the code, it's crucial to understand the two main types of sorting: natural ordering and custom sorting. Natural ordering applies when elements inherently know how to compare themselves (e.g., Integer, String implement the Comparable interface). Custom sorting, on the other hand, allows you to define specific rules for comparison, which is essential for sorting custom objects or applying non-default logic.

flowchart TD
    A[Start Sorting Process] --> B{Is Natural Ordering Sufficient?}
    B -->|Yes| C[Use Collections.sort() for Comparable elements]
    B -->|No| D[Define Custom Sorting Logic]
    D --> E{Implement Comparator Interface}
    E --> F[Use Collections.sort() with Comparator]
    E --> G[Use List.sort() with Comparator]
    C --> H[Sorted List]
    F --> H
    G --> H

Decision flow for choosing a sorting method in Java.

Sorting with Collections.sort()

The java.util.Collections class provides a static sort() method that is the most common way to sort a List. This method has two overloaded versions: one for natural ordering and another that accepts a Comparator.

1. Natural Ordering

If the elements in your List implement the Comparable interface (like String, Integer, Double, etc.), you can sort them directly using Collections.sort(List<T> list).

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

public class NaturalSortExample {
    public static void main(String[] args) {
        List<String> names = new ArrayList<>();
        names.add("Alice");
        names.add("Charlie");
        names.add("Bob");
        names.add("David");

        System.out.println("Original List: " + names);

        // Sort using natural ordering
        Collections.sort(names);

        System.out.println("Sorted List (Natural Order): " + names);

        List<Integer> numbers = new ArrayList<>();
        numbers.add(5);
        numbers.add(2);
        numbers.add(8);
        numbers.add(1);

        System.out.println("\nOriginal Numbers: " + numbers);
        Collections.sort(numbers);
        System.out.println("Sorted Numbers (Natural Order): " + numbers);
    }
}

Example of sorting a List using natural ordering with Collections.sort().

2. Custom Sorting with Comparator

When you need to sort objects that don't have a natural order, or you want to sort them based on criteria different from their natural order, you use the Collections.sort(List<T> list, Comparator<? super T> c) method. This requires providing an implementation of the java.util.Comparator interface.

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

class Person {
    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Person{" +
               "name='" + name + '\'' +
               ", age=" + age +
               '}';
    }
}

public class CustomSortExample {
    public static void main(String[] args) {
        List<Person> people = new ArrayList<>();
        people.add(new Person("Alice", 30));
        people.add(new Person("Charlie", 25));
        people.add(new Person("Bob", 35));
        people.add(new Person("David", 25));

        System.out.println("Original People List: " + people);

        // Sort by age using an anonymous inner class Comparator
        Collections.sort(people, new Comparator<Person>() {
            @Override
            public int compare(Person p1, Person p2) {
                return Integer.compare(p1.getAge(), p2.getAge());
            }
        });
        System.out.println("Sorted by Age: " + people);

        // Sort by name using a Lambda expression (Java 8+)
        Collections.sort(people, (p1, p2) -> p1.getName().compareTo(p2.getName()));
        System.out.println("Sorted by Name: " + people);

        // Sort by age, then by name for ties (Java 8+ Comparator.comparing)
        Collections.sort(people, Comparator.comparing(Person::getAge).thenComparing(Person::getName));
        System.out.println("Sorted by Age then Name: " + people);
    }
}

Examples of custom sorting using Comparator with Collections.sort().

Sorting with List.sort() (Java 8+)

Since Java 8, the List interface itself provides a sort() method. This method takes a Comparator as an argument and sorts the list in place. It's often preferred over Collections.sort() when you already have a List object, as it's a method of the list itself rather than a static utility method.

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

// Assuming the Person class from the previous example is available

public class ListSortExample {
    public static void main(String[] args) {
        List<Person> people = new ArrayList<>();
        people.add(new Person("Alice", 30));
        people.add(new Person("Charlie", 25));
        people.add(new Person("Bob", 35));
        people.add(new Person("David", 25));

        System.out.println("Original People List: " + people);

        // Sort by age using List.sort() with a lambda
        people.sort((p1, p2) -> Integer.compare(p1.getAge(), p2.getAge()));
        System.out.println("Sorted by Age (List.sort()): " + people);

        // Sort by name in reverse order using List.sort() and Comparator.reverseOrder()
        people.sort(Comparator.comparing(Person::getName).reversed());
        System.out.println("Sorted by Name (Reverse, List.sort()): " + people);
    }
}

Example of sorting a List using the List.sort() method with a Comparator.

Sorting in Reverse Order

You can easily sort a list in reverse order using a few different approaches:

1. Using Collections.reverseOrder()

Pass Collections.reverseOrder() as the Comparator to Collections.sort() or List.sort() for elements with natural ordering. For custom objects, you can use Collections.reverseOrder(Comparator<T> cmp).

2. Using Comparator.reversed()

If you have an existing Comparator (or create one with Comparator.comparing()), you can chain .reversed() to it to get a Comparator that sorts in the opposite direction.

3. Manually Reversing the List

Sort the list in ascending order first, then use Collections.reverse(List<?> list) to reverse the order of all elements.

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ReverseSortExample {
    public static void main(String[] args) {
        List<String> fruits = new ArrayList<>();
        fruits.add("Apple");
        fruits.add("Orange");
        fruits.add("Banana");
        fruits.add("Grape");

        System.out.println("Original Fruits: " + fruits);

        // Method 1: Using Collections.reverseOrder() for natural ordering
        Collections.sort(fruits, Collections.reverseOrder());
        System.out.println("Reverse Sorted (Collections.reverseOrder()): " + fruits);

        // Reset list for next example
        fruits = new ArrayList<>();
        fruits.add("Apple");
        fruits.add("Orange");
        fruits.add("Banana");
        fruits.add("Grape");

        // Method 2: Using Comparator.reversed() with List.sort()
        fruits.sort(Comparator.naturalOrder().reversed());
        System.out.println("Reverse Sorted (Comparator.reversed()): " + fruits);

        // Reset list for next example
        fruits = new ArrayList<>();
        fruits.add("Apple");
        fruits.add("Orange");
        fruits.add("Banana");
        fruits.add("Grape");

        // Method 3: Sort then reverse
        Collections.sort(fruits); // Sort ascending first
        Collections.reverse(fruits); // Then reverse the entire list
        System.out.println("Reverse Sorted (Sort then Reverse): " + fruits);
    }
}

Examples of sorting a List in reverse order.