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.markscan overflow for big or negative numbers and sort wrongly.Integer.compare(a, b)is always safe.