Introduction

Comparable interface

class Student implements Comparable<Student> {
    int age;

    @Override
    public int compareTo(Student o) {
        return Integer.compare(this.age, o.age);
    }
}

// Usage:
Collections.sort(students); // will use compareTo

Comparator (class/lambda)

// Old-school (anonymous class)
Comparator<User> byAge = new Comparator<>() {
    public int compare(User a, User b) {
        return a.getAge() - b.getAge();
    }
};

// Modern (Lambda)
Comparator<User> byAge = 
		(a, b) -> Integer.compare(a.getAge(), b.getAge());
		
// Cleaner modern way (recommended)
students.sort(Comparator.comparingInt(Student::getAge));

Comparator chaining

Sort by age, then name

Comparator<User> cmp =
    Comparator.comparingInt(User::getAge)
              .thenComparing(User::getName);

// clean and modern       
students.sort(
    Comparator.comparing(Student::getAge)
              .thenComparing(Student::getName)
);