Sorting collections is a foundational Java skill. An ArrayList does not sort itself — you must explicitly define how items should be ordered. This updated guide on javatechig.com covers all modern ways to sort an ArrayList in Java using the JDK APIs, including ascending/descending order, custom object sorting, and best practices used in production environments.
1. Sorting with Collections.sort() (Basic)
Java provides the Collections.sort() method for basic list sorting.
Example – Sort Integers (Ascending)
List<Integer> numbers = new ArrayList<>(Arrays.asList(5, 2, 9, 1, 4));
Collections.sort(numbers);
System.out.println(numbers); // Output: [1, 2, 4, 5, 9]
This uses the natural ordering of elements.
2. Sorting in Reverse Order
To reverse sort:
Collections.sort(numbers, Collections.reverseOrder());
System.out.println(numbers); // Output: [9, 5, 4, 2, 1]
This uses Comparator.reverseOrder() under the hood.
3. Sorting Custom Objects
When sorting custom objects, define how attributes determine order.
Example Class
public class Student {
private String name;
private int age;
// Constructor, getters
}
Sort by Age (Ascending)
Collections.sort(students, new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
return Integer.compare(s1.getAge(), s2.getAge());
}
});
Or using a lambda (Java 8+):
students.sort(Comparator.comparingInt(Student::getAge));
4. Sorting with Comparable
If your class implements Comparable, you define the natural order.
Implementing Comparable
public class Student implements Comparable<Student> {
@Override
public int compareTo(Student other) {
return this.name.compareTo(other.name);
}
}
Sort by Natural Order
Collections.sort(students);
This sorts based on the logic inside compareTo().
5. Sorting in Descending Order with Comparator
For custom reverse sorting without modifying the class:
students.sort(Comparator.comparing(Student::getName).reversed());
This sorts by name in descending order.
6. Java 8+ Stream API Sorting
Java Streams enable sorting in a functional style.
Ascending
List<String> sorted =
names.stream()
.sorted()
.collect(Collectors.toList());
Custom Sort
List<Student> sortedByAge =
students.stream()
.sorted(Comparator.comparingInt(Student::getAge))
.collect(Collectors.toList());
Stream sorting does not modify the original list unless reassigned.
7. Multi-Field Sorting
Sort by multiple fields (e.g., age then name):
students.sort(
Comparator.comparingInt(Student::getAge)
.thenComparing(Student::getName)
);
This produces deterministic ordering when primary values are equal.
8. Sorting with Null Safety
If your list may contain nulls:
students.sort(
Comparator.nullsFirst(Comparator.comparing(Student::getName))
);
Use nullsLast() when you want non-null items first.
9. Performance Considerations
- Sorting is O(n log n) using TimSort in Java Collections
- Avoid sorting inside loops
- Use
List.sort()instead ofCollections.sort()where possible - Reuse comparators for consistency
10. Common Mistakes
Modifying List During Sort
Avoid structural modifications while sorting — use immutable copies if needed.
Ignoring Natural Ordering
Always provide explicit comparators for custom types.
Using Legacy APIs
Avoid deprecated or third-party sort utilities when standard JDK APIs suffice.
Best Practices (2026 Updated)
- Prefer
List.sort()with lambda or method references - Use Streams for transformations before sorting
- Encapsulate comparator logic for reusability
- Protect against null pointers with
Comparator.nullsFirst()ornullsLast()


