What Is The Comparator? A Comprehensive Guide

Comparator definition is crucial for sorting and ordering objects in Java, and compare.edu.vn offers a deep dive into its functionalities. This guide explores comparators, their importance, and how they can be used effectively to enhance data manipulation in various applications, providing you with the tools to make informed decisions. Explore the benefits of comparator implementation, comparator interface, and comparator example.

1. Understanding Comparators

A comparator is an interface in Java used to define a custom ordering for objects of a class. It is part of the Java Collections Framework and plays a crucial role in sorting and ordering elements in collections. This section explores the fundamental aspects of comparators, including their definition, purpose, and how they differ from comparable interfaces.

1.1. Definition of a Comparator

In Java, a comparator is an interface (java.util.Comparator) that provides a way to define a total ordering on some collection of objects. Unlike the Comparable interface, which requires the class itself to implement the comparison logic, a comparator is a separate class that can be created to compare objects of another class.

The comparator interface consists of a single method:

int compare(Object obj1, Object obj2);

This method compares two objects and returns an integer value indicating their relative order:

  • Negative value: obj1 is less than obj2.
  • Zero: obj1 is equal to obj2.
  • Positive value: obj1 is greater than obj2.

1.2. Purpose of Using Comparators

The primary purpose of using comparators is to provide flexibility in sorting and ordering objects. Comparators are particularly useful in scenarios where:

  • The class does not implement the Comparable interface.
  • The default ordering provided by the Comparable interface is not suitable.
  • Multiple ordering criteria are required for the same class.
  • The sorting logic needs to be customized based on specific requirements.

Comparators allow developers to define different sorting strategies without modifying the original class. This promotes code reusability and maintainability.

1.3. Comparator vs. Comparable: Key Differences

Both Comparator and Comparable are used for sorting and ordering objects in Java, but they have distinct differences:

Feature Comparator Comparable
Interface java.util.Comparator java.lang.Comparable
Implementation Separate class Implemented by the class itself
Method int compare(Object obj1, Object obj2) int compareTo(Object obj)
Modification Does not require modification of the original class Requires modification of the original class
Flexibility Allows multiple sorting strategies for the same class Provides a single, natural ordering for the class
Use Case External sorting logic or multiple sorting criteria needed Default ordering for the class is sufficient or the class needs a natural ordering

Comparable is suitable when the class has a natural ordering that is always the same. Comparator is used when you need to define different ordering strategies or when the class does not implement Comparable.

2. Creating a Comparator in Java

Creating a comparator involves implementing the java.util.Comparator interface and providing the comparison logic in the compare() method. This section guides you through the steps to create a comparator, providing code examples and best practices.

2.1. Implementing the Comparator Interface

To create a comparator, you need to implement the java.util.Comparator interface. This involves creating a class that implements the interface and overrides the compare() method.

Here’s a basic example of creating a comparator for a Student class:

import java.util.Comparator;

public class Student {
    private int id;
    private String name;
    private double gpa;

    public Student(int id, String name, double gpa) {
        this.id = id;
        this.name = name;
        this.gpa = gpa;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public double getGpa() {
        return gpa;
    }

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

class SortByGPA implements Comparator<Student> {
    @Override
    public int compare(Student s1, Student s2) {
        return Double.compare(s1.getGpa(), s2.getGpa());
    }
}

In this example, the SortByGPA class implements the Comparator<Student> interface. The compare() method compares two Student objects based on their GPA.

2.2. Writing the compare() Method

The compare() method is the heart of the comparator. It defines the logic for comparing two objects and determining their relative order. The method should return:

  • A negative integer if the first object is less than the second object.
  • Zero if the first object is equal to the second object.
  • A positive integer if the first object is greater than the second object.

Here are some common patterns for writing the compare() method:

  • Comparing Numbers:

    public int compare(Student s1, Student s2) {
        return Integer.compare(s1.getId(), s2.getId());
    }
  • Comparing Strings:

    public int compare(Student s1, Student s2) {
        return s1.getName().compareTo(s2.getName());
    }
  • Comparing Multiple Fields:

    public int compare(Student s1, Student s2) {
        int nameComparison = s1.getName().compareTo(s2.getName());
        if (nameComparison != 0) {
            return nameComparison;
        }
        return Double.compare(s2.getGpa(), s2.getGpa());
    }

2.3. Best Practices for Creating Comparators

  • Handle Null Values: Ensure your comparator handles null values gracefully to avoid NullPointerException.

    public int compare(Student s1, Student s2) {
        if (s1 == null && s2 == null) return 0;
        if (s1 == null) return -1;
        if (s2 == null) return 1;
        return Integer.compare(s1.getId(), s2.getId());
    }
  • Consider Edge Cases: Test your comparator with various edge cases to ensure it behaves as expected.

  • Use Static Constants: If the comparator is stateless, define it as a static constant to avoid unnecessary object creation.

    public static final Comparator<Student> SORT_BY_ID = (s1, s2) -> Integer.compare(s1.getId(), s2.getId());
  • Use Comparator Chaining: Combine multiple comparators to create complex sorting logic.

    Comparator<Student> chainedComparator = Comparator.comparing(Student::getName)
            .thenComparing(Student::getGpa);

3. Using Comparators with Collections

Comparators are commonly used with collections in Java to sort and order elements. This section demonstrates how to use comparators with various collection types, including lists, sets, and maps.

3.1. Sorting Lists with Comparators

The Collections.sort() method can be used to sort a list using a comparator. This method takes a list and a comparator as arguments.

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

public class ComparatorExample {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student(101, "Alice", 3.8));
        students.add(new Student(102, "Bob", 3.6));
        students.add(new Student(103, "Charlie", 3.9));

        System.out.println("Before sorting: " + students);

        Collections.sort(students, new SortByGPA());

        System.out.println("After sorting by GPA: " + students);
    }
}

In this example, the Collections.sort() method sorts the list of Student objects based on their GPA, using the SortByGPA comparator.

3.2. Using Comparators with Sorted Sets

Sorted sets, such as TreeSet, maintain their elements in a sorted order. You can provide a comparator to the TreeSet constructor to define the sorting order.

import java.util.Set;
import java.util.TreeSet;

public class ComparatorExample {
    public static void main(String[] args) {
        Set<Student> students = new TreeSet<>(new SortByGPA());
        students.add(new Student(101, "Alice", 3.8));
        students.add(new Student(102, "Bob", 3.6));
        students.add(new Student(103, "Charlie", 3.9));

        System.out.println("Sorted set by GPA: " + students);
    }
}

In this example, the TreeSet is created with the SortByGPA comparator, ensuring that the Student objects are stored in ascending order of GPA.

3.3. Using Comparators with Sorted Maps

Sorted maps, such as TreeMap, maintain their entries in a sorted order based on the keys. You can provide a comparator to the TreeMap constructor to define the sorting order for the keys.

import java.util.Map;
import java.util.TreeMap;

public class ComparatorExample {
    public static void main(String[] args) {
        Map<Student, String> studentMap = new TreeMap<>(new SortByGPA());
        studentMap.put(new Student(101, "Alice", 3.8), "Math");
        studentMap.put(new Student(102, "Bob", 3.6), "Science");
        studentMap.put(new Student(103, "Charlie", 3.9), "English");

        System.out.println("Sorted map by GPA: " + studentMap);
    }
}

In this example, the TreeMap is created with the SortByGPA comparator, ensuring that the Student objects (used as keys) are stored in ascending order of GPA.

4. Advanced Comparator Techniques

Beyond basic comparator implementations, Java offers several advanced techniques for creating more flexible and powerful comparators. This section explores comparator chaining, reverse ordering, and using lambda expressions for comparators.

4.1. Comparator Chaining

Comparator chaining involves combining multiple comparators to create a complex sorting logic. This is useful when you need to sort objects based on multiple criteria.

The thenComparing() method in the Comparator interface allows you to chain comparators. Here’s an example:

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

public class ComparatorExample {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student(101, "Alice", 3.8));
        students.add(new Student(102, "Bob", 3.6));
        students.add(new Student(103, "Alice", 3.9));

        Comparator<Student> chainedComparator = Comparator.comparing(Student::getName)
                .thenComparing(Student::getGpa);

        Collections.sort(students, chainedComparator);

        System.out.println("Sorted by name then GPA: " + students);
    }
}

In this example, the chainedComparator first compares students by their name and then, if the names are the same, compares them by their GPA.

4.2. Reverse Ordering

Sometimes, you need to sort objects in reverse order. The reversed() method in the Comparator interface allows you to easily reverse the order of a comparator.

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

public class ComparatorExample {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student(101, "Alice", 3.8));
        students.add(new Student(102, "Bob", 3.6));
        students.add(new Student(103, "Charlie", 3.9));

        Comparator<Student> sortByGpa = Comparator.comparing(Student::getGpa);
        Comparator<Student> sortByGpaReversed = sortByGpa.reversed();

        Collections.sort(students, sortByGpaReversed);

        System.out.println("Sorted by GPA in reverse order: " + students);
    }
}

In this example, the sortByGpaReversed comparator sorts the students in descending order of their GPA.

4.3. Using Lambda Expressions for Comparators

Lambda expressions provide a concise way to create comparators, especially for simple comparison logic.

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

public class ComparatorExample {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student(101, "Alice", 3.8));
        students.add(new Student(102, "Bob", 3.6));
        students.add(new Student(103, "Charlie", 3.9));

        Comparator<Student> sortByGpa = (s1, s2) -> Double.compare(s1.getGpa(), s2.getGpa());

        Collections.sort(students, sortByGpa);

        System.out.println("Sorted by GPA using lambda: " + students);
    }
}

In this example, the lambda expression (s1, s2) -> Double.compare(s1.getGpa(), s2.getGpa()) defines a comparator that compares students based on their GPA.

5. Real-World Applications of Comparators

Comparators are used in a wide range of applications where sorting and ordering of objects are required. This section explores some real-world scenarios where comparators are particularly useful.

5.1. Sorting Data in E-Commerce Applications

In e-commerce applications, comparators can be used to sort products based on various criteria, such as price, rating, popularity, and relevance.

For example, you can create comparators to sort products by:

  • Price (ascending or descending)
  • Customer rating (highest to lowest)
  • Number of sales (most to least)
  • Date added (newest to oldest)
import java.util.Comparator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

class Product {
    private int id;
    private String name;
    private double price;
    private double rating;

    public Product(int id, String name, double price, double rating) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.rating = rating;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public double getPrice() {
        return price;
    }

    public double getRating() {
        return rating;
    }

    @Override
    public String toString() {
        return "Product{" +
                "id=" + id +
                ", name='" + name + ''' +
                ", price=" + price +
                ", rating=" + rating +
                '}';
    }
}

public class ComparatorExample {
    public static void main(String[] args) {
        List<Product> products = new ArrayList<>();
        products.add(new Product(1, "Laptop", 1200.0, 4.5));
        products.add(new Product(2, "Smartphone", 800.0, 4.2));
        products.add(new Product(3, "Tablet", 300.0, 4.8));

        Comparator<Product> sortByPrice = Comparator.comparing(Product::getPrice);
        Comparator<Product> sortByRating = Comparator.comparing(Product::getRating).reversed();

        Collections.sort(products, sortByPrice);
        System.out.println("Sorted by price: " + products);

        Collections.sort(products, sortByRating);
        System.out.println("Sorted by rating: " + products);
    }
}

5.2. Ordering Search Results

In search applications, comparators can be used to order search results based on relevance, date, or other criteria.

For example, you can create comparators to sort search results by:

  • Relevance score (highest to lowest)
  • Date modified (newest to oldest)
  • Number of views (most to least)
import java.util.Comparator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

class SearchResult {
    private String title;
    private String url;
    private double relevance;
    private String dateModified;

    public SearchResult(String title, String url, double relevance, String dateModified) {
        this.title = title;
        this.url = url;
        this.relevance = relevance;
        this.dateModified = dateModified;
    }

    public String getTitle() {
        return title;
    }

    public String getUrl() {
        return url;
    }

    public double getRelevance() {
        return relevance;
    }

    public String getDateModified() {
        return dateModified;
    }

    @Override
    public String toString() {
        return "SearchResult{" +
                "title='" + title + ''' +
                ", url='" + url + ''' +
                ", relevance=" + relevance +
                ", dateModified='" + dateModified + ''' +
                '}';
    }
}

public class ComparatorExample {
    public static void main(String[] args) {
        List<SearchResult> searchResults = new ArrayList<>();
        searchResults.add(new SearchResult("Java Tutorial", "java.com", 0.8, "2023-01-01"));
        searchResults.add(new SearchResult("Java Examples", "example.com", 0.9, "2023-02-01"));
        searchResults.add(new SearchResult("Java Documentation", "docs.com", 0.7, "2023-03-01"));

        Comparator<SearchResult> sortByRelevance = Comparator.comparing(SearchResult::getRelevance).reversed();

        Collections.sort(searchResults, sortByRelevance);
        System.out.println("Sorted by relevance: " + searchResults);
    }
}

5.3. Sorting Data in Financial Applications

In financial applications, comparators can be used to sort transactions, portfolios, and other financial data based on various criteria, such as date, amount, and type.

For example, you can create comparators to sort transactions by:

  • Date (oldest to newest or newest to oldest)
  • Amount (highest to lowest or lowest to highest)
  • Type (e.g., credit, debit)
import java.util.Comparator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

class Transaction {
    private int id;
    private String date;
    private double amount;
    private String type;

    public Transaction(int id, String date, double amount, String type) {
        this.id = id;
        this.date = date;
        this.amount = amount;
        this.type = type;
    }

    public int getId() {
        return id;
    }

    public String getDate() {
        return date;
    }

    public double getAmount() {
        return amount;
    }

    public String getType() {
        return type;
    }

    @Override
    public String toString() {
        return "Transaction{" +
                "id=" + id +
                ", date='" + date + ''' +
                ", amount=" + amount +
                ", type='" + type + ''' +
                '}';
    }
}

public class ComparatorExample {
    public static void main(String[] args) {
        List<Transaction> transactions = new ArrayList<>();
        transactions.add(new Transaction(1, "2023-01-01", 100.0, "credit"));
        transactions.add(new Transaction(2, "2023-02-01", 200.0, "debit"));
        transactions.add(new Transaction(3, "2023-03-01", 150.0, "credit"));

        Comparator<Transaction> sortByDate = Comparator.comparing(Transaction::getDate);
        Comparator<Transaction> sortByAmount = Comparator.comparing(Transaction::getAmount).reversed();

        Collections.sort(transactions, sortByDate);
        System.out.println("Sorted by date: " + transactions);

        Collections.sort(transactions, sortByAmount);
        System.out.println("Sorted by amount: " + transactions);
    }
}

6. Comparator Interface and Its Methods

The Comparator interface in Java is a powerful tool for defining custom sorting logic. Understanding its methods and how to use them effectively is essential for leveraging its capabilities. This section delves into the key methods of the Comparator interface and provides examples of their usage.

6.1. compare(T o1, T o2) Method

The compare(T o1, T o2) method is the core of the Comparator interface. It compares two objects and returns an integer value indicating their relative order. The return value should be:

  • Negative if o1 is less than o2.
  • Zero if o1 is equal to o2.
  • Positive if o1 is greater than o2.

Here’s an example of how to use the compare() method to sort a list of Employee objects by their salary:

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

class Employee {
    private int id;
    private String name;
    private double salary;

    public Employee(int id, String name, double salary) {
        this.id = id;
        this.name = name;
        this.salary = salary;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public double getSalary() {
        return salary;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", name='" + name + ''' +
                ", salary=" + salary +
                '}';
    }
}

public class ComparatorExample {
    public static void main(String[] args) {
        List<Employee> employees = new ArrayList<>();
        employees.add(new Employee(1, "Alice", 50000.0));
        employees.add(new Employee(2, "Bob", 60000.0));
        employees.add(new Employee(3, "Charlie", 55000.0));

        Comparator<Employee> sortBySalary = new Comparator<Employee>() {
            @Override
            public int compare(Employee e1, Employee e2) {
                return Double.compare(e1.getSalary(), e2.getSalary());
            }
        };

        Collections.sort(employees, sortBySalary);
        System.out.println("Sorted by salary: " + employees);
    }
}

6.2. reversed() Method

The reversed() method returns a comparator that imposes the reverse ordering of the original comparator. This is useful when you need to sort objects in descending order instead of ascending order.

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

public class ComparatorExample {
    public static void main(String[] args) {
        List<Employee> employees = new ArrayList<>();
        employees.add(new Employee(1, "Alice", 50000.0));
        employees.add(new Employee(2, "Bob", 60000.0));
        employees.add(new Employee(3, "Charlie", 55000.0));

        Comparator<Employee> sortBySalary = Comparator.comparing(Employee::getSalary);
        Comparator<Employee> sortBySalaryReversed = sortBySalary.reversed();

        Collections.sort(employees, sortBySalaryReversed);
        System.out.println("Sorted by salary in reverse order: " + employees);
    }
}

6.3. thenComparing(Comparator<? super T> other) Method

The thenComparing(Comparator<? super T> other) method is used to chain multiple comparators together. It returns a new comparator that first uses the original comparator to compare objects, and then uses the specified comparator to compare objects that are equal according to the original comparator.

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

public class ComparatorExample {
    public static void main(String[] args) {
        List<Employee> employees = new ArrayList<>();
        employees.add(new Employee(1, "Alice", 50000.0));
        employees.add(new Employee(2, "Bob", 60000.0));
        employees.add(new Employee(3, "Alice", 55000.0));

        Comparator<Employee> sortByNameThenSalary = Comparator.comparing(Employee::getName)
                .thenComparing(Employee::getSalary);

        Collections.sort(employees, sortByNameThenSalary);
        System.out.println("Sorted by name then salary: " + employees);
    }
}

6.4. comparing(Function<? super T, ? extends U> keyExtractor) Method

The comparing(Function<? super T, ? extends U> keyExtractor) method returns a comparator that compares objects based on the result of applying the specified key extractor function. This is a convenient way to create comparators for specific fields or properties of an object.

import java.util.Comparator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;

public class ComparatorExample {
    public static void main(String[] args) {
        List<Employee> employees = new ArrayList<>();
        employees.add(new Employee(1, "Alice", 50000.0));
        employees.add(new Employee(2, "Bob", 60000.0));
        employees.add(new Employee(3, "Charlie", 55000.0));

        Comparator<Employee> sortByName = Comparator.comparing(Employee::getName);

        Collections.sort(employees, sortByName);
        System.out.println("Sorted by name: " + employees);
    }
}

6.5. nullsFirst(Comparator<? super T> comparator) and nullsLast(Comparator<? super T> comparator) Methods

The nullsFirst(Comparator<? super T> comparator) and nullsLast(Comparator<? super T> comparator) methods return comparators that handle null values. nullsFirst places null values at the beginning of the sorted list, while nullsLast places them at the end.

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

public class ComparatorExample {
    public static void main(String[] args) {
        List<Employee> employees = new ArrayList<>();
        employees.add(new Employee(1, "Alice", 50000.0));
        employees.add(new Employee(2, "Bob", 60000.0));
        employees.add(null);
        employees.add(new Employee(3, "Charlie", 55000.0));

        Comparator<Employee> sortByName = Comparator.comparing(Employee::getName, Comparator.nullsFirst(String::compareTo));

        Collections.sort(employees, sortByName);
        System.out.println("Sorted by name with nulls first: " + employees);
    }
}

7. Common Pitfalls and How to Avoid Them

When working with comparators, it’s easy to make mistakes that can lead to unexpected behavior or errors. This section outlines some common pitfalls and provides strategies for avoiding them.

7.1. Inconsistent Comparison Logic

One of the most common pitfalls is implementing comparison logic that is inconsistent or violates the contract of the Comparator interface. The compare() method must be transitive, symmetric, and consistent.

  • Transitivity: If compare(a, b) > 0 and compare(b, c) > 0, then compare(a, c) > 0.
  • Symmetry: If compare(a, b) == 0, then compare(b, a) == 0.
  • Consistency: Multiple invocations of compare(a, b) should consistently return the same result, provided that the objects a and b have not been modified.

To avoid inconsistent comparison logic, carefully review your implementation and ensure that it adheres to these principles. Use unit tests to verify that your comparator behaves correctly in various scenarios.

7.2. Handling Null Values Incorrectly

Failing to handle null values correctly can lead to NullPointerException or incorrect sorting results. Always check for null values in your compare() method and handle them appropriately.

public int compare(Student s1, Student s2) {
    if (s1 == null && s2 == null) return 0;
    if (s1 == null) return -1;
    if (s2 == null) return 1;
    return Integer.compare(s1.getId(), s2.getId());
}

Alternatively, you can use the Comparator.nullsFirst() or Comparator.nullsLast() methods to handle null values.

7.3. Performance Issues

Complex comparison logic can lead to performance issues, especially when sorting large collections. Avoid performing expensive operations in your compare() method, such as database lookups or complex calculations.

Instead, pre-compute the values needed for comparison and store them in the object. This can significantly improve the performance of your comparator.

7.4. Not Implementing Serializable

If your comparator is used in serializable data structures, such as TreeSet or TreeMap, it must also implement the Serializable interface. Otherwise, you may encounter NotSerializableException when attempting to serialize the data structure.

import java.io.Serializable;
import java.util.Comparator;

class SortByGPA implements Comparator<Student>, Serializable {
    @Override
    public int compare(Student s1, Student s2) {
        return Double.compare(s1.getGpa(), s2.getGpa());
    }
}

8. Benefits of Using Comparators

Using comparators in Java offers several benefits, including increased flexibility, code reusability, and improved maintainability. This section highlights the key advantages of using comparators in your Java applications.

8.1. Flexibility in Sorting

Comparators provide a high degree of flexibility in sorting objects. You can define multiple comparators for the same class, each providing a different sorting strategy. This allows you to sort objects based on various criteria without modifying the original class.

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

public class ComparatorExample {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student(101, "Alice", 3.8));
        students.add(new Student(102, "Bob", 3.6));
        students.add(new Student(103, "Charlie", 3.9));

        Comparator<Student> sortByName = Comparator.comparing(Student::getName);
        Comparator<Student> sortByGPA = Comparator.comparing(Student::getGpa);

        Collections.sort(students, sortByName);
        System.out.println("Sorted by name: " + students);

        Collections.sort(students, sortByGPA);
        System.out.println("Sorted by GPA: " + students);
    }
}

8.2. Code Reusability

Comparators can be reused across multiple classes and applications. Once you define a comparator, you can use it to sort objects in any collection that contains objects of the same type. This promotes code reusability and reduces the amount of code you need to write.

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

public class ComparatorExample {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student(101, "Alice", 3.8));
        students.add(new Student(102, "Bob", 3.6));
        students.add(new Student(103, "Charlie", 3.9));

        List<Employee> employees = new ArrayList<>();
        employees.add(new Employee(1, "Alice", 50000.0));
        employees.add(new Employee(2, "Bob", 60000.0));
        employees.add(new Employee(3, "Charlie", 55000.0));

        Comparator<String> sortByName = String::compareTo;

        Collections.sort(students, (s1, s2) -> sortByName.compare(s1.getName(), s2.getName()));
        System.out.println("Sorted students by name: " + students);

        Collections.sort(employees, (e1, e2) -> sortByName.compare(e1.getName(), e2.getName()));
        System.out.println("Sorted employees by name: " + employees);
    }
}

8.3. Improved Maintainability

Comparators improve the maintainability of your code by separating the sorting logic from the class being sorted. This makes it easier to update or modify the sorting logic without affecting the rest of the code.


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

public class ComparatorExample {
    public static void main(String[] args) {
        List<Student> students

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *