Java Comparable & Comparator
In this page:
Natural Sorting with Comparable
You can define a default, natural sort order for your own custom classes by implementing the Comparable interface and overriding its compareTo method. Collections like TreeSet and TreeMap will automatically use this natural ordering unless you explicitly supply something else.
Example: Natural Sorting with Comparable
import java.util.*;
public class Main {
static class Person implements Comparable<Person> {
String name; int age;
Person(String name, int age) { this.name = name; this.age = age; }
public int compareTo(Person other) { return Integer.compare(age, other.age); }
public String toString() { return name + "(" + age + ")"; }
}
public static void main(String[] args) {
List<Person> people = new ArrayList<>(List.of(new Person("Bo", 30), new Person("Al", 20)));
Collections.sort(people);
System.out.println(people);
}
}
Login to try C/C++/Java/PHP code in the editor
Custom Sorting with Comparator
If you want to sort the same objects in several different ways without touching their class definition, you can define a separate class implementing the Comparator interface for each ordering you need. This decouples the sorting logic entirely from the object being sorted.
Example: Custom Sorting with Comparator
import java.util.*;
public class Main {
static class ByName implements Comparator<String> {
public int compare(String a, String b) { return a.compareTo(b); }
}
public static void main(String[] args) {
List<String> names = new ArrayList<>(List.of("Zoe", "Amy", "Max"));
names.sort(new ByName());
System.out.println(names);
}
}
Login to try C/C++/Java/PHP code in the editor
Comparator Lambda Syntax
You can write ad-hoc comparators quickly using lambda expressions instead of declaring a whole named class purely for one comparison. This is the most common way comparators are written in modern Java code, especially for one-off sorts.
Example: Comparator Lambda Syntax
import java.util.*;
public class Main {
public static void main(String[] args) {
List<String> names = new ArrayList<>(List.of("Zoe", "Amy", "Max"));
names.sort((a, b) -> a.compareTo(b));
System.out.println(names);
}
}
Login to try C/C++/Java/PHP code in the editor
Chaining Comparators
You can chain several comparators together using the thenComparing() method to define fallback sorting rules, so that when two elements tie on the primary comparison, the next comparator in the chain breaks the tie, and so on down the chain.
Example: Chaining Comparators
import java.util.*;
public class Main {
record Person(String name, int age) {}
public static void main(String[] args) {
List<Person> people = new ArrayList<>(List.of(new Person("Amy", 30), new Person("Amy", 20)));
people.sort(Comparator.comparing(Person::name).thenComparing(Person::age));
System.out.println(people);
}
}
Login to try C/C++/Java/PHP code in the editor
Null-Safe Comparators
Sorting a collection that contains null elements with a custom comparator can throw a NullPointerException the moment the comparator tries to compare against one. You can guard against this by wrapping your comparator with Comparator.nullsFirst() or nullsLast(), which push nulls to whichever end of the ordering you choose.
Example: Null-Safe Comparators
import java.util.*;
public class Main {
public static void main(String[] args) {
List<String> names = new ArrayList<>(Arrays.asList("Zoe", null, "Amy"));
names.sort(Comparator.nullsFirst(Comparator.naturalOrder()));
System.out.println(names);
}
}
Login to try C/C++/Java/PHP code in the editor
Chapter Quiz — Complete all 4 topics to unlock
0/4 topics done
Complete these topics first: