Both Comparable and Comparator can be used to compare the elements of the list, which allows you to sort the list with your own logic.

Configuration
Java Compilation:
Java Runtime:
JDK 11.0.12
JRE HotSpot 11.0.12
Some built-in Java functions like Collections.sort can be used to sort a list. In order for the sorting function to perform, we need to define how to compare the elements of the list.
Let say we have a Student class which has 5 fields:
public class Student { int id; String firstName; String lastName; int height; int age; public Student(int id, String firstName, String lastName, int height, int age) { this.id = id; this.firstName = firstName; this.lastName = lastName; this.height = height; this.age = age; } public void printOut() { System.out.println("id = " + id + " firstName = " + firstName + " lastName = " + lastName + " height = " + height + " age = " + age); } }
And we would like to compare the class by lastName and then firstName alphabetically, one way is to use Comparable:
  • make the Student class implements the Comparable interface
  • implements the compareTo method
like below:
public class Student implements Comparable<Student> { int id; String firstName; String lastName; int height; int age; public Student(int id, String firstName, String lastName, int height, int age) { this.id = id; this.firstName = firstName; this.lastName = lastName; this.height = height; this.age = age; } // Custom comparison logic - compare lastName then firstName // return -1 if you determined this object is less than the comparing object // return 1 if you determined this object is large than the comparing object // return 0 if 2 objects are the same public int compareTo(Student student) { // We can simply use the compareTo method of the String class if (lastName.compareTo(student.lastName) != 0) { return lastName.compareTo(student.lastName); } else { return firstName.compareTo(student.firstName); } } public void printOut() { System.out.println("id = " + id + " firstName = " + firstName + " lastName = " + lastName + " height = " + height + " age = " + age); } }
To test it, create some Student objects and apply Collection.sort:
public static void main(String[] args) { ArrayList<Student> students = new ArrayList<>(); students.add(new comparable.Student(1, "Sam", "Smith", 160, 11)); students.add(new comparable.Student(2, "Tom", "Johnson", 168, 12)); students.add(new comparable.Student(3, "Mary", "Lamb", 120, 10)); students.add(new comparable.Student(4, "Susan", "Lee", 130, 11)); students.add(new comparable.Student(5, "Peter", "Smith", 155, 12)); Collections.sort(students); for (Student student : students) { student.printOut(); } }
Output:
id = 2 firstName = Tom lastName = Johnson height = 168 age = 12
id = 3 firstName = Mary lastName = Lamb height = 120 age = 10
id = 4 firstName = Susan lastName = Lee height = 130 age = 11
id = 5 firstName = Peter lastName = Smith height = 155 age = 12
id = 1 firstName = Sam lastName = Smith height = 160 age = 11
However, sometimes you would like to have multiple ways of comparing the Student class, or would not want the Student class to implement any interface. In this case, Comparator could be used.
There is no need to change Student class. So keeping the Student class:
public class Student { int id; String firstName; String lastName; int height; int age; public Student(int id, String firstName, String lastName, int height, int age) { this.id = id; this.firstName = firstName; this.lastName = lastName; this.height = height; this.age = age; } public void printOut() { System.out.println("id = " + id + " firstName = " + firstName + " lastName = " + lastName + " height = " + height + " age = " + age); } }
What we have to do is to new a custom Comparator. As we want to compare by lastName and then firstName, create StudentComparatorByName:
import java.util.Comparator; public class StudentByNameComparator implements Comparator<Student> { // Custom comparison logic - compare lastName then firstName // return -1 if you want o1 is less then o2 // return 1 if you want o1 is larger then o2 // return 0 if you want they are the same @Override public int compare(Student o1, Student o2) { if (o1.lastName.compareTo(o2.lastName) != 0) { return o1.lastName.compareTo(o2.lastName); } else { return o1.firstName.compareTo(o2.firstName); } } }
Now the Comparator is ready for use. To use it, just create a new instance and put it in the second argument of the sort function:
public class MainClass { public static void main(String[] args) { List<Student> students = new ArrayList<>(); students.add(new Student(1, "Sam", "Smith", 160, 11)); students.add(new Student(2, "Tom", "Johnson", 168, 12)); students.add(new Student(3, "Mary", "Lamb", 120, 10)); students.add(new Student(4, "Susan", "Lee", 130, 11)); students.add(new Student(5, "Peter", "Smith", 155, 12)); Collections.sort(students, new StudentByNameComparator()); for (Student student : students) { student.printOut(); } } }
Output:
id = 2 firstName = Tom lastName = Johnson height = 168 age = 12
id = 3 firstName = Mary lastName = Lamb height = 120 age = 10
id = 4 firstName = Susan lastName = Lee height = 130 age = 11
id = 5 firstName = Peter lastName = Smith height = 155 age = 12
id = 1 firstName = Sam lastName = Smith height = 160 age = 11
To compare the class by height, just create another Comparator:
import java.util.Comparator; public class StudentByHeightComparator implements Comparator<Student> { @Override public int compare(Student o1, Student o2) { return o1.height - o2.height; } }
With the same Student list:
public class MainClass { public static void main(String[] args) { List<Student> students = new ArrayList<>(); students.add(new Student(1, "Sam", "Smith", 160, 11)); students.add(new Student(2, "Tom", "Johnson", 168, 12)); students.add(new Student(3, "Mary", "Lamb", 120, 10)); students.add(new Student(4, "Susan", "Lee", 130, 11)); students.add(new Student(5, "Peter", "Smith", 155, 12)); Collections.sort(students, new StudentByHeightComparator()); for (Student student : students) { student.printOut(); } } }
Output:
id = 3 firstName = Mary lastName = Lamb height = 120 age = 10
id = 4 firstName = Susan lastName = Lee height = 130 age = 11
id = 5 firstName = Peter lastName = Smith height = 155 age = 12
id = 1 firstName = Sam lastName = Smith height = 160 age = 11
id = 2 firstName = Tom lastName = Johnson height = 168 age = 12