← Back to Home

Module 4: Comparators and Using sort()

Module Overview

Learn about Comparators for flexible object comparison and how to use Java's built-in sorting mechanisms.

Learning Objectives

Detailed Explanations

Introduction to Comparators

While the Comparable interface provides a natural ordering for a class, the Comparator interface allows you to define multiple custom orderings for objects without modifying their classes.

When to Use Comparators

  • When you can't modify the class to implement Comparable
  • When you need multiple different ways to compare objects
  • When the natural ordering isn't suitable for your specific use case
  • For classes where a natural ordering doesn't make sense (e.g., a Person class could be sorted by name, age, etc.)

Implementing a Comparator

The Comparator interface has a single abstract method to implement:

public interface Comparator<T> {
    int compare(T o1, T o2);
}
                

Similar to compareTo(), the compare() method should:

  • Return a negative value if o1 < o2
  • Return zero if o1 equals o2
  • Return a positive value if o1 > o2

Example Implementation

// A comparator that sorts Product objects by price
public class ProductPriceComparator implements Comparator<Product> {
    @Override
    public int compare(Product p1, Product p2) {
        // Compare prices
        return p1.getPrice().compareTo(p2.getPrice());
    }
}

// A comparator that sorts Product objects by title
public class ProductTitleComparator implements Comparator<Product> {
    @Override
    public int compare(Product p1, Product p2) {
        // Compare titles alphabetically
        return p1.getTitle().compareTo(p2.getTitle());
    }
}
                

Using Java's Sorting Mechanisms

Java provides several ways to sort collections of objects:

Sorting Using Collections.sort()

// Sorting by natural ordering (using Comparable)
List<String> names = Arrays.asList("Charlie", "Alice", "Bob");
Collections.sort(names);  // ["Alice", "Bob", "Charlie"]

// Sorting with a Comparator
List<Product> products = getProductList();
Collections.sort(products, new ProductPriceComparator());  // Sorted by price
Collections.sort(products, new ProductTitleComparator());  // Sorted by title
                

Sorting Arrays

// Sorting an array of Comparable objects
String[] namesArray = {"Charlie", "Alice", "Bob"};
Arrays.sort(namesArray);

// Sorting an array with a Comparator
Product[] productsArray = getProductArray();
Arrays.sort(productsArray, new ProductPriceComparator());
                

Advanced Comparator Techniques

Chaining Comparisons

For complex sorting requirements, you can chain multiple comparisons:

public class ProductPriceRatingComparator implements Comparator<Product> {
    @Override
    public int compare(Product p1, Product p2) {
        // First compare by price
        int priceComparison = p1.getPrice().compareTo(p2.getPrice());
        
        // If prices are equal, compare by rating
        if (priceComparison == 0) {
            return Double.compare(p2.getRating(), p1.getRating());  // Higher rating first
        }
        
        return priceComparison;
    }
}
                

Using Lambda Expressions (Java 8+)

In modern Java, you can use lambda expressions to create Comparators concisely:

// Sorting by price
Collections.sort(products, (p1, p2) -> p1.getPrice().compareTo(p2.getPrice()));

// Sorting by title
Collections.sort(products, (p1, p2) -> p1.getTitle().compareTo(p2.getTitle()));

// Chaining comparisons using Comparator methods
Comparator<Product> comparator = Comparator
    .comparing(Product::getPrice)
    .thenComparing(Product::getRating, Comparator.reverseOrder())
    .thenComparing(Product::getTitle);

Collections.sort(products, comparator);
                

Reversing Order

To reverse the ordering of a Comparator:

// Using the reversed() method (Java 8+)
Collections.sort(products, new ProductPriceComparator().reversed());

// For natural ordering, use reverseOrder()
Collections.sort(names, Comparator.reverseOrder());
                

Comparator vs. Comparable

Decision guidelines for choosing between Comparator and Comparable:

Criterion Comparable Comparator
Control over class Need to modify class No need to modify class
Ordering types Single natural ordering Multiple orderings possible
Usage with sort Collections.sort(list) Collections.sort(list, comparator)
Common examples String, Integer, Date Custom sorting strategies

Resources