Java Sorting with Comparators
A Comparator holds a sorting rule outside the class it orders. One class of objects can then be sorted in several ways, without changing the class itself.
Sorting by name with a helper class
ByName implements Comparator and compares the name fields. The students print in name order, not score order.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("Cid", 88));
students.add(new Student("Ana", 92));
students.add(new Student("Ben", 75));
Collections.sort(students, new ByName());
for (Student student : students) {
System.out.println(student.name);
}
}
}
class Student {
String name;
int score;
Student(String name, int score) {
this.name = name;
this.score = score;
}
}
class ByName implements Comparator<Student> {
public int compare(Student a, Student b) {
return a.name.compareTo(b.name);
}
}A second rule, by score
ByScore compares the score fields instead of the names. The same three students now print from the lowest score up.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("Cid", 88));
students.add(new Student("Ana", 92));
students.add(new Student("Ben", 75));
Collections.sort(students, new ByScore());
for (Student student : students) {
System.out.println(student.name + ": " + student.score);
}
}
}
class Student {
String name;
int score;
Student(String name, int score) {
this.name = name;
this.score = score;
}
}
class ByScore implements Comparator<Student> {
public int compare(Student a, Student b) {
return Integer.compare(a.score, b.score);
}
}Reversing the answer
ByScoreDescending swaps the two values before comparing them. The scores now print from the highest down.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("Cid", 88));
students.add(new Student("Ana", 92));
students.add(new Student("Ben", 75));
Collections.sort(students, new ByScoreDescending());
for (Student student : students) {
System.out.println(student.name + ": " + student.score);
}
}
}
class Student {
String name;
int score;
Student(String name, int score) {
this.name = name;
this.score = score;
}
}
class ByScoreDescending implements Comparator<Student> {
public int compare(Student a, Student b) {
return Integer.compare(b.score, a.score);
}
}Example
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("Cid", 88));
students.add(new Student("Ana", 92));
students.add(new Student("Ben", 75));
Collections.sort(students, new ByName());
for (Student student : students) {
System.out.println(student.name + ": " + student.score);
}
Collections.sort(students, new ByScoreDescending());
for (Student student : students) {
System.out.println(student.name + ": " + student.score);
}
}
}
class Student {
String name;
int score;
Student(String name, int score) {
this.name = name;
this.score = score;
}
}
class ByName implements Comparator<Student> {
public int compare(Student a, Student b) {
return a.name.compareTo(b.name);
}
}
class ByScoreDescending implements Comparator<Student> {
public int compare(Student a, Student b) {
return Integer.compare(b.score, a.score);
}
}Key points
- A Comparator is a separate object whose compare method orders two values.
- A helper class that implements Comparator carries one rule, such as order by name.
- Collections.sort takes the list and the comparator as its two arguments.
- Two comparators over one list print two different orders.
- Reversing the two values inside compare sorts in the opposite direction.
In this example, one list prints in name order under ByName, then in score order from the top under ByScoreDescending, and the Student class never changes.
Note
The class being sorted needs no Comparable implementation when a comparator does the work.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
Why use a Comparator instead of Comparable?