Java Advanced Sorting

Sorting data efficiently is a critical task in software development. Java provides robust tools like Comparator and Comparable interfaces to customize sorting logic. This tutorial by The Coding College explains how to use these interfaces for advanced sorting techniques, ensuring your code is efficient and maintainable.

Key Differences Between Comparable and Comparator

FeatureComparableComparator
PurposeUsed to define natural sorting of objects.Used for custom sorting logic.
Interface Locationjava.lang package.java.util package.
MethodcompareTo(Object o)compare(Object o1, Object o2)
ModificationsChanges are made within the object itself.Sorting logic is external to the object.
Use CaseSingle sorting logic.Multiple or flexible sorting logic.

1. Using Comparable for Natural Sorting

The Comparable interface is used to define the natural sorting order of objects. Implement the compareTo() method in the class whose objects need to be sorted.

Example: Sorting Students by Roll Number

import java.util.*;

class Student implements Comparable<Student> {
    int rollNumber;
    String name;

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

    @Override
    public int compareTo(Student other) {
        return this.rollNumber - other.rollNumber; // Ascending order
    }

    @Override
    public String toString() {
        return "Student{rollNumber=" + rollNumber + ", name='" + name + "'}";
    }
}

public class Main {
    public static void main(String[] args) {
        List<Student> students = Arrays.asList(
            new Student(3, "Alice"),
            new Student(1, "Bob"),
            new Student(2, "Charlie")
        );

        Collections.sort(students); // Uses compareTo() method
        System.out.println(students);
    }
}

Output:

[Student{rollNumber=1, name='Bob'}, Student{rollNumber=2, name='Charlie'}, Student{rollNumber=3, name='Alice'}]

2. Using Comparator for Custom Sorting

The Comparator interface is used when you need multiple or custom sorting logic. Define the sorting logic externally using the compare() method.

Example: Sorting Students by Name

import java.util.*;

class Student {
    int rollNumber;
    String name;

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

    @Override
    public String toString() {
        return "Student{rollNumber=" + rollNumber + ", name='" + name + "'}";
    }
}

public class Main {
    public static void main(String[] args) {
        List<Student> students = Arrays.asList(
            new Student(3, "Alice"),
            new Student(1, "Bob"),
            new Student(2, "Charlie")
        );

        // Custom sorting by name
        students.sort(Comparator.comparing(student -> student.name));

        System.out.println(students);
    }
}

Output:

[Student{rollNumber=3, name='Alice'}, Student{rollNumber=1, name='Bob'}, Student{rollNumber=2, name='Charlie'}]

Advanced Comparator Techniques

1. Sorting with Multiple Criteria

import java.util.*;

class Student {
    int rollNumber;
    String name;

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

    @Override
    public String toString() {
        return "Student{rollNumber=" + rollNumber + ", name='" + name + "'}";
    }
}

public class Main {
    public static void main(String[] args) {
        List<Student> students = Arrays.asList(
            new Student(2, "Charlie"),
            new Student(1, "Alice"),
            new Student(1, "Bob")
        );

        // Sort by rollNumber, then by name
        students.sort(
            Comparator.comparing((Student s) -> s.rollNumber)
                      .thenComparing(s -> s.name)
        );

        System.out.println(students);
    }
}

Output:

[Student{rollNumber=1, name='Alice'}, Student{rollNumber=1, name='Bob'}, Student{rollNumber=2, name='Charlie'}]

2. Reverse Sorting

students.sort(Comparator.comparing(student -> student.name).reversed());

Practical Use Cases

Sorting a List of Strings:

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.sort(Comparator.reverseOrder());
System.out.println(names);

Output:

[Charlie, Bob, Alice]

Sorting a Map by Values:

Map<String, Integer> map = new HashMap<>();
map.put("Alice", 10);
map.put("Bob", 5);
map.put("Charlie", 20);

map.entrySet()
   .stream()
   .sorted(Map.Entry.comparingByValue())
   .forEach(System.out::println);

Output:

Bob=5
Alice=10
Charlie=20

Conclusion

Java’s Comparator and Comparable interfaces offer powerful ways to implement sorting logic for collections and custom objects.

  • Use Comparable for natural sorting defined within the class.
  • Use Comparator for flexible, external sorting logic.

Practice these techniques with your own examples and visit The Coding College for more advanced Java tutorials!

Leave a Comment