Java Sorting Objects with Comparable
Sorting objects needs an order, and a plain object list has none. Comparable is the interface a class implements to give its objects a natural order.
A sort with no rule
The null second argument asks sort to use the natural order of each object. Student defines no order, so the run fails.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("Ana", 92));
students.add(new Student("Ben", 75));
Collections.sort(students, null);
System.out.println(students.size());
}
}
class Student {
String name;
int score;
Student(String name, int score) {
this.name = name;
this.score = score;
}
}What compareTo answers
compareTo compares the scores of two students. Its sign places the first score after, before, or equal to the second.
public class Main {
public static void main(String[] args) {
Student ana = new Student("Ana", 92);
Student ben = new Student("Ben", 75);
Student cid = new Student("Cid", 92);
System.out.println(ana.compareTo(ben));
System.out.println(ben.compareTo(ana));
System.out.println(ana.compareTo(cid));
}
}
class Student implements Comparable<Student> {
String name;
int score;
Student(String name, int score) {
this.name = name;
this.score = score;
}
public int compareTo(Student other) {
return Integer.compare(this.score, other.score);
}
}The same sort, with a rule
Student now implements Comparable with a score order. The same sort prints the students from the lowest score up.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("Ana", 92));
students.add(new Student("Ben", 75));
students.add(new Student("Cid", 88));
Collections.sort(students);
for (Student student : students) {
System.out.println(student.name + ": " + student.score);
}
}
}
class Student implements Comparable<Student> {
String name;
int score;
Student(String name, int score) {
this.name = name;
this.score = score;
}
public int compareTo(Student other) {
return Integer.compare(this.score, other.score);
}
}Example
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("Dan", 64));
students.add(new Student("Ana", 92));
students.add(new Student("Ben", 75));
students.add(new Student("Cid", 88));
Collections.sort(students);
for (Student student : students) {
System.out.println(student.name + ": " + student.score);
}
}
}
class Student implements Comparable<Student> {
String name;
int score;
Student(String name, int score) {
this.name = name;
this.score = score;
}
public int compareTo(Student other) {
return Integer.compare(this.score, other.score);
}
}Key points
- Collections.sort asks each object to compare itself with the next one.
- Without a comparison rule, the sort fails at runtime with a ClassCastException.
- A class supplies the rule by writing implements Comparable and a compareTo method.
- compareTo returns a negative number, zero, or a positive number for before, equal, or after.
- Integer.compare answers that sign from two int values in one call.
In this example, compareTo orders the students by score, so one loop prints the class from the lowest score to the highest.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
What must a class provide before Collections.sort can order its objects?