๐ŸŽ“ A1Learner
๐Ÿ”
0 of 40 lessons completed

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?