public class Employee implements Comparable<Employee> {
    private String name;
    private int id;
    private double salary;
    
    public Employee(String name, int id, double salary) {
        this.name = name;
        this.id = id;
        this.salary = salary;
    }
    
    @Override
    public int compareTo(Employee other) {
        // Natural ordering by employee ID
        return Integer.compare(this.id, other.id);
        // Use String
        return this.name.compare(other.name);
        // etc...
    }
    
    // Getters omitted for brevity
}

Implementation:

  • Our class has to implements Comparable<MyClass>.
  • We have to @Override the compareTo(MyClass other) function.

Equals

If .equals() is also implemented on that class, they need to be consistent!

(Note that overriding .equals() is not mandatory just to compare.)

Null Fields

If a field can be null, be sure to handle that before using .compareTo().

Using

  • Collections.sort(list)
  • list.sort(null) (uses natural ordering)
  • Arrays.sort(array) (natural ordering)
  • TreeSet/TreeMap maintain order according to natural order automatically
  • list.stream().sorted().collect(Collectors.toList())

We can use Collections.sort(list) on our List<MyClass> after implementing Comparable<MyClass>.

Implementing compareTo(MyClass other) possibilities

The return int of this.compareTo(other) can take three possible values:

  • return < 0 meaning that this comes before
  • return == 0 meaning equals
  • return > 0 meaning this comes after

Compare on Primitive If we want to sort our class by some primitive like int, we can use Integer.compare(this.id, other.id) or Double.compare().

Compare on Object We can either just compare on a single field of our class using this.field.compareTo(other.field) if it’s not a primitive type.

Compare multiple fields We can implement a priority by using multiple comparisons:

// First on string
int dep = this.department.compareTo(other.department); 
if (dep != 0) return result; 
 
// Then by years
int service = Integer.compare(this.years, other.years);
if (result != 0) return service; 
 
// Then by name
return this.name.compareTo(other.name);