Sorting Your Own Objects: Comparable and Comparator

Java needs to know what “smaller” means

Numbers and Strings already know how to compare themselves. For your own class, you tell Java. A compare method returns a negative number if the first item should come first, positive if the second should, and 0 if they're equal.

Option 1: Comparable – the natural order

import java.util.ArrayList;
import java.util.Collections;

class Song implements Comparable<Song> {
    String title;
    int seconds;

    Song(String title, int seconds) {
        this.title = title;
        this.seconds = seconds;
    }

    public int compareTo(Song other) {            // shorter songs first
        return Integer.compare(this.seconds, other.seconds);
    }

    public String toString() {
        return title + " (" + seconds + "s)";
    }
}

public class Main {
    public static void main(String[] args) {
        ArrayList<Song> playlist = new ArrayList<Song>();
        playlist.add(new Song("Rain", 245));
        playlist.add(new Song("Sun", 180));
        playlist.add(new Song("Wind", 210));
        Collections.sort(playlist);
        System.out.println(playlist);
    }
}

Output

[Sun (180s), Wind (210s), Rain (245s)]

Option 2: Comparator – any order you like

A Comparator is a separate rule you pass to the sort. Great for “sort by marks, highest first; if equal, by name A–Z”:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

class Student {
    String name;
    int marks;

    Student(String name, int marks) {
        this.name = name;
        this.marks = marks;
    }
}

class ByMarksThenName implements Comparator<Student> {
    public int compare(Student a, Student b) {
        if (a.marks != b.marks) return Integer.compare(b.marks, a.marks);  // b first: highest marks first
        return a.name.compareTo(b.name);                                   // tie: A to Z
    }
}

public class Main {
    public static void main(String[] args) {
        ArrayList<Student> list = new ArrayList<Student>();
        list.add(new Student("Neha", 82));
        list.add(new Student("Arjun", 95));
        list.add(new Student("Kabir", 82));
        list.add(new Student("Divya", 70));
        Collections.sort(list, new ByMarksThenName());
        for (Student s : list) System.out.println(s.name + " " + s.marks);
    }
}

Output

Arjun 95
Kabir 82
Neha 82
Divya 70

Tip: In Java 8 you can also write the rule as a lambda: Collections.sort(list, (a, b) -> Integer.compare(b.marks, a.marks));

Common mistake: Returning a.marks - b.marks can overflow for big or negative numbers and sort wrongly. Integer.compare(a, b) is always safe.

HOME LABS COMMUNITY DASHBOARD