← Back to Home

Module 3: Comparable

Module Overview

Learn about the Comparable interface and how to implement natural ordering for objects in Java.

Learning Objectives

Detailed Explanations

Introduction to the Comparable Interface

The Comparable interface in Java is used to define a "natural ordering" between objects of the same type. This allows collections of objects to be sorted and compared in a meaningful way.

Interface Declaration

public interface Comparable<T> {
    // Returns negative if this < other, zero if this == other, positive if this > other
    public int compareTo(T other);
}
                

Many built-in Java classes such as String, Integer, and Date implement Comparable, allowing them to be naturally ordered.

Implementing the Comparable Interface

To make your custom class comparable, you need to implement the Comparable interface and provide a compareTo method.

Example Implementation

public class Student implements Comparable<Student> {
    private String name;
    private double gpa;
    
    public Student(String name, double gpa) {
        this.name = name;
        this.gpa = gpa;
    }
    
    // Getters and setters...
    
    @Override
    public int compareTo(Student other) {
        // Compare based on GPA (higher GPA comes first)
        if (this.gpa > other.gpa) {
            return -1;
        } else if (this.gpa < other.gpa) {
            return 1;
        } else {
            // If GPAs are equal, compare by name
            return this.name.compareTo(other.name);
        }
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return Double.compare(student.gpa, gpa) == 0 && 
               Objects.equals(name, student.name);
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(name, gpa);
    }
}
                

The compareTo Method Contract

The compareTo method must follow these rules:

  • It must return a negative integer if this object is "less than" the other object
  • It must return zero if this object is "equal to" the other object
  • It must return a positive integer if this object is "greater than" the other object
  • It should be consistent with equals (a.equals(b) should be true if and only if a.compareTo(b) == 0)
  • It should be transitive (if a.compareTo(b) > 0 and b.compareTo(c) > 0, then a.compareTo(c) > 0)

Using Comparable Objects

Once a class implements Comparable, its instances can be:

  • Sorted using Collections.sort() or Arrays.sort()
  • Used as elements in sorted collections like TreeSet or TreeMap
  • Compared directly using the compareTo method

Example Usage

// Creating a list of students
List<Student> students = new ArrayList<>();
students.add(new Student("Alice", 3.8));
students.add(new Student("Bob", 3.5));
students.add(new Student("Charlie", 4.0));

// Sorting the list using the natural ordering (defined by compareTo)
Collections.sort(students);

// Now students will be sorted by GPA (highest first), then by name
for (Student student : students) {
    System.out.println(student.getName() + ": " + student.getGpa());
}
                

When to Implement Comparable

You should implement Comparable when:

  • Your class has a clear, natural ordering (like numbers, dates, or alphabetical names)
  • You want to enable sorting of objects of your class
  • You need to use your objects in sorted collections

If different orderings are needed for the same class, consider using Comparator (covered in Module 4) instead of or in addition to Comparable.

Resources