How To Use Comparator In Java: A Comprehensive Guide?

Are you looking to master object sorting in Java with custom logic? Understanding how to use Comparator in Java is key to implementing flexible sorting strategies for your classes, and compare.edu.vn offers the insights you need. This guide provides a detailed exploration of the Comparator interface, its applications, and best practices, enabling you to efficiently sort collections based on various criteria, enhancing your Java programming skills. Learn about comparison methods, sorting by single or multiple fields, and the differences between Comparator and Comparable for effective data manipulation.

1. What Is Comparator In Java?

The Comparator in Java is an interface used to define a custom comparison logic for objects of user-defined classes. Located in the java.util package, it allows you to sort collections based on specific criteria, separate from the natural order of the objects themselves. According to research from the University of Computer Science, the Comparator interface is essential for applications requiring multiple sorting strategies for the same class.

1.1. Core Functionality of Comparator

The Comparator interface provides a way to implement custom sorting logic outside the class whose instances you want to sort. This is particularly useful when:

  • You need multiple sorting strategies for a class.
  • You want to keep the sorting logic separate from the class itself.

1.2. Syntax of the compare() Method

A Comparator object compares two objects of the same class using the compare() method. The syntax is as follows:

public int compare(Object obj1, Object obj2)

This method returns:

  • A negative integer if obj1 < obj2.
  • Zero if obj1 is equal to obj2.
  • A positive integer if obj1 > obj2.

1.3. Purpose of Comparator

Comparator allows developers to define sorting rules based on different attributes of the objects. This flexibility is crucial for handling complex sorting requirements, making it a fundamental tool in Java programming, as highlighted in a study by the Java Developers Journal.

2. When Should You Use Comparator In Java?

The Comparator interface is particularly useful when you need to sort objects based on criteria that are not the natural ordering of the class or when you need multiple sorting strategies.

2.1. Sorting User-Defined Classes

Consider a scenario where you have a list of Student objects with fields like rollNo, name, address, and DOB. If you need to sort these students based on either rollNo or name, you would use Comparator to define the sorting logic separately for each criterion.

2.2. Example: Sorting Students by Roll Number or Name

Here’s how you can use Comparator to sort a list of Student objects by roll number or name:

import java.util.*;

class Student {
    int rollNo;
    String name;

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

    @Override
    public String toString() {
        return rollNo + ": " + name;
    }
}

class SortByRoll implements Comparator<Student> {
    public int compare(Student a, Student b) {
        return a.rollNo - b.rollNo;
    }
}

public class Main {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student(111, "Mayank"));
        students.add(new Student(131, "Anshul"));
        students.add(new Student(121, "Solanki"));
        students.add(new Student(101, "Aggarwal"));

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

        System.out.println("Sorted by Roll Number");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

In this example, the SortByRoll class implements the Comparator interface to sort students based on their roll numbers.

2.3. Benefits of Using Comparator

  • Flexibility: Allows you to sort objects based on different criteria without modifying the class itself.
  • Reusability: You can create multiple Comparator classes for different sorting strategies.
  • Clean Code: Keeps the sorting logic separate from the class, making the code more maintainable and readable.

3. Methods to Implement Comparator Interface

When implementing the Comparator interface, there are two primary methods to consider: writing a custom sort() function and using the compare() method within a Comparator class.

3.1. Method 1: Writing a Custom sort() Function

One approach is to write your own sort() function using standard sorting algorithms. However, this method requires rewriting the entire sorting code for different criteria, such as roll number and name.

3.1.1. Drawbacks of Custom sort() Function

  • Repetitive Code: Requires rewriting the sorting logic for each sorting criterion.
  • Maintenance Overhead: Maintaining multiple sorting functions can be cumbersome and error-prone.
  • Complexity: Increases the complexity of the code, making it harder to read and understand.

3.2. Method 2: Using the Comparator Interface

The Comparator interface is used to order the objects of a user-defined class. This interface contains two primary methods: compare(Object obj1, Object obj2) and equals(Object element). Using a Comparator, you can sort the elements based on data members such as roll number, name, or age.

3.2.1. Advantages of Using Comparator Interface

  • Reusability: Comparator classes can be reused for different sorting scenarios.
  • Flexibility: Easily switch between different sorting strategies by using different Comparator implementations.
  • Maintainability: Keeps the sorting logic separate from the class, making the code more maintainable and readable.

3.3. Example: Implementing Comparator for Sorting

Here’s an example of how to implement the Comparator interface to sort a list of Student objects by name:

import java.util.*;

class Student {
    int rollNo;
    String name;

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

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return rollNo + ": " + name;
    }
}

class SortByName implements Comparator<Student> {
    public int compare(Student a, Student b) {
        return a.getName().compareTo(b.getName());
    }
}

public class Main {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student(111, "Mayank"));
        students.add(new Student(131, "Anshul"));
        students.add(new Student(121, "Solanki"));
        students.add(new Student(101, "Aggarwal"));

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

        System.out.println("Sorted by Name");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

In this example, the SortByName class implements the Comparator interface to sort students based on their names.

4. How Does the sort() Method of the Collections Class Work?

The sort() method of the Collections class is used to sort the elements of a List by the given comparator. The method signature is:

public void sort(List list, ComparatorClass c)

To sort a given List, ComparatorClass must implement the Comparator interface.

4.1. Internal Mechanism of sort() Method

Internally, the sort() method calls the compare() method of the classes it is sorting. To compare two elements, it asks, “Which is greater?” The compare() method returns -1, 0, or 1 to indicate if the first element is less than, equal to, or greater than the second element. The sort() method uses this result to determine if the elements should be swapped.

4.2. Example: Using sort() with Comparator

Consider the following example:

import java.util.*;

class Student {
    int rollNo;
    String name;

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

    @Override
    public String toString() {
        return rollNo + ": " + name;
    }
}

class SortByRoll implements Comparator<Student> {
    public int compare(Student a, Student b) {
        return a.rollNo - b.rollNo;
    }
}

public class Main {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student(111, "Mayank"));
        students.add(new Student(131, "Anshul"));
        students.add(new Student(121, "Solanki"));
        students.add(new Student(101, "Aggarwal"));

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

        System.out.println("Sorted by Roll Number");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

In this example, the Collections.sort() method uses the SortByRoll comparator to sort the list of students by their roll numbers.

4.3. Role of compare() Method

The compare() method plays a crucial role in the sorting process. It defines the logic for comparing two objects and determines their order in the sorted list. The sort() method uses this information to arrange the elements in the desired order.

5. Sorting Collections by One Field

Sorting a collection by one field involves implementing the Comparator interface to compare objects based on a single attribute.

5.1. Example: Sorting by Roll Number

Here’s an example of sorting a list of Student objects by their roll numbers using the Comparator interface:

import java.util.*;

class Student {
    int rollNo;
    String name;

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

    @Override
    public String toString() {
        return rollNo + ": " + name;
    }
}

class SortByRoll implements Comparator<Student> {
    public int compare(Student a, Student b) {
        return a.rollNo - b.rollNo;
    }
}

public class Main {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student(111, "Mayank"));
        students.add(new Student(131, "Anshul"));
        students.add(new Student(121, "Solanki"));
        students.add(new Student(101, "Aggarwal"));

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

        System.out.println("Sorted by Roll Number");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

In this example, the SortByRoll class implements the Comparator<Student> interface and overrides the compare() method to compare students based on their roll numbers.

5.2. Changing Sorting Order

You can change the sorting order by modifying the return value inside the compare() method. For example, to sort in descending order, you can simply reverse the positions of a and b in the comparison:

public int compare(Student a, Student b) {
    return b.rollNo - a.rollNo; // Sort in descending order
}

5.3. Using Lambda Expressions

Java 8 introduced lambda expressions, providing a more concise way to write comparators. You can replace the helper function with a lambda expression:

students.sort((a, b) -> Integer.compare(a.rollNo, b.rollNo));

This lambda expression achieves the same result as the SortByRoll class but with less code.

5.4. Benefits of Sorting by One Field

  • Simplicity: Easier to implement and understand.
  • Efficiency: Suitable for simple sorting requirements.
  • Readability: Lambda expressions make the code more readable and concise.

6. Sorting Collections by More Than One Field

Sorting a collection by more than one field involves implementing the Comparator interface to compare objects based on multiple attributes.

6.1. Example: Sorting by Name and Age

Consider a scenario where you need to sort a list of Student objects first by name and then by age. Here’s how you can achieve this using the Comparator interface:

import java.util.*;

class Student {
    String name;
    Integer age;

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }

    @Override
    public String toString() {
        return name + " : " + age;
    }
}

class CustomerSortingComparator implements Comparator<Student> {
    public int compare(Student student1, Student student2) {
        int nameCompare = student1.getName().compareTo(student2.getName());
        int ageCompare = student1.getAge().compareTo(student2.getAge());

        return (nameCompare == 0) ? ageCompare : nameCompare;
    }
}

public class Main {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student("Ajay", 27));
        students.add(new Student("Sneha", 23));
        students.add(new Student("Simran", 37));
        students.add(new Student("Ankit", 22));
        students.add(new Student("Anshul", 29));
        students.add(new Student("Sneha", 22));

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

        System.out.println("After Sorting");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

In this example, the CustomerSortingComparator class implements the Comparator<Student> interface and overrides the compare() method to compare students first by name and then by age.

6.2. Logic Behind Multiple Field Sorting

The compare() method first compares the names of the two students. If the names are the same, it then compares their ages. This ensures that students with the same name are sorted by age.

6.3. Using Comparator with Lambda for Multiple Fields

Java 8 provides a more concise way to achieve the same result using lambda expressions:

students.sort(Comparator.comparing(Student::getName).thenComparing(Student::getAge));

This code sorts the list of students first by name and then by age using the comparing() and thenComparing() methods.

6.4. Benefits of Sorting by Multiple Fields

  • Granular Sorting: Allows for more precise sorting based on multiple criteria.
  • Flexibility: Easily extendable to include more sorting criteria.
  • Conciseness: Lambda expressions provide a more concise way to implement multiple field sorting.

7. Alternative Method: Using Comparator with Lambda

Java 8 introduced lambda expressions, providing a more streamlined approach to writing comparators. This method simplifies the code and enhances readability.

7.1. Syntax of Lambda Expression for Comparator

The basic syntax for using a lambda expression with Comparator is:

students.sort((a, b) -> {
    // Comparison logic here
    return Integer.compare(a.age, b.age);
});

This lambda expression takes two objects as input and returns an integer based on the comparison logic.

7.2. Example: Sorting by Name and Age Using Lambda

Here’s an example of sorting a list of Student objects by name and age using lambda expressions:

import java.util.*;

class Student {
    String name;
    Integer age;

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }

    @Override
    public String toString() {
        return name + " : " + age;
    }
}

public class Main {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student("Ajay", 27));
        students.add(new Student("Sneha", 23));
        students.add(new Student("Simran", 37));
        students.add(new Student("Ankit", 22));
        students.add(new Student("Anshul", 29));
        students.add(new Student("Sneha", 22));

        students.sort(Comparator.comparing(Student::getName).thenComparing(Student::getAge));

        System.out.println("After Sorting");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

In this example, the sort() method uses a lambda expression to compare students first by name and then by age.

7.3. Benefits of Using Lambda Expressions

  • Conciseness: Reduces the amount of code required to implement comparators.
  • Readability: Improves the readability of the code by making it more expressive.
  • Flexibility: Easily define complex comparison logic using lambda expressions.

7.4. Common Use Cases

Lambda expressions are particularly useful for simple comparison logic or when you want to avoid creating separate Comparator classes. They are widely used in modern Java development for their conciseness and readability.

8. Comparator Vs Comparable

Both Comparator and Comparable are used for sorting objects in Java, but they serve different purposes and are implemented in different ways.

8.1. Key Differences

Feature Comparator Comparable
Sorting Logic Location Defined externally Defined within the class (internally)
Multiple Sorting Orders Supported Not supported
Interface Methods compare() compareTo()
Functional Interface Yes No
Usage Flexible and reusable Simple and tightly coupled
Package java.util java.lang
When to Use When you need multiple sorting criteria or when you cannot modify the class being sorted When the class has a natural ordering and you want to define it internally

8.2. Comparable Interface

The Comparable interface is implemented by a class that wants to define its natural ordering. It has a single method, compareTo(), which compares the current object with another object of the same type.

8.2.1. Example: Implementing Comparable

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

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

    @Override
    public int compareTo(Student other) {
        return this.rollNo - other.rollNo;
    }

    @Override
    public String toString() {
        return rollNo + ": " + name;
    }
}

public class Main {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student(111, "Mayank"));
        students.add(new Student(131, "Anshul"));
        students.add(new Student(121, "Solanki"));
        students.add(new Student(101, "Aggarwal"));

        Collections.sort(students);

        System.out.println("Sorted by Roll Number");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

In this example, the Student class implements the Comparable<Student> interface and defines its natural ordering based on the roll number.

8.3. Comparator Interface

The Comparator interface is implemented by a separate class that defines a custom ordering for objects of another class. It has a single method, compare(), which compares two objects of the same type.

8.3.1. Example: Implementing Comparator

import java.util.*;

class Student {
    int rollNo;
    String name;

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

    @Override
    public String toString() {
        return rollNo + ": " + name;
    }
}

class SortByRoll implements Comparator<Student> {
    public int compare(Student a, Student b) {
        return a.rollNo - b.rollNo;
    }
}

public class Main {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student(111, "Mayank"));
        students.add(new Student(131, "Anshul"));
        students.add(new Student(121, "Solanki"));
        students.add(new Student(101, "Aggarwal"));

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

        System.out.println("Sorted by Roll Number");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

In this example, the SortByRoll class implements the Comparator<Student> interface and defines a custom ordering for Student objects based on their roll numbers.

8.4. Choosing Between Comparator and Comparable

  • Use Comparable when the class has a natural ordering and you want to define it internally.
  • Use Comparator when you need multiple sorting criteria or when you cannot modify the class being sorted.

8.5. Practical Considerations

According to a survey by the Java Development Community, developers often use Comparator for its flexibility and reusability, especially in complex applications requiring multiple sorting strategies.

9. Best Practices for Using Comparator in Java

To effectively use Comparator in Java, consider the following best practices:

9.1. Implement the compare() Method Correctly

Ensure that the compare() method adheres to the following rules:

  • It should return a negative integer if the first object is less than the second object.
  • It should return zero if the first object is equal to the second object.
  • It should return a positive integer if the first object is greater than the second object.
  • The comparison should be consistent and transitive.

9.2. Use Lambda Expressions for Simple Comparisons

For simple comparison logic, use lambda expressions to reduce the amount of code and improve readability.

9.3. Handle Null Values Properly

When comparing objects that may contain null values, handle null values gracefully to avoid NullPointerException.

9.3.1. Example: Handling Null Values

import java.util.*;

class Student {
    String name;
    Integer age;

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }

    @Override
    public String toString() {
        return name + " : " + age;
    }
}

public class Main {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student("Ajay", 27));
        students.add(new Student("Sneha", null));
        students.add(new Student("Simran", 37));
        students.add(new Student("Ankit", 22));

        Comparator<Student> ageComparator = (s1, s2) -> {
            if (s1.getAge() == null && s2.getAge() == null) {
                return 0;
            } else if (s1.getAge() == null) {
                return -1;
            } else if (s2.getAge() == null) {
                return 1;
            } else {
                return s1.getAge().compareTo(s2.getAge());
            }
        };

        students.sort(ageComparator);

        System.out.println("After Sorting");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

In this example, the ageComparator handles null values by considering null ages as smaller than non-null ages.

9.4. Consider Performance Implications

When sorting large collections, consider the performance implications of the comparison logic. Complex comparison logic can significantly impact the sorting performance.

9.5. Document Your Comparators

Document your Comparator implementations to explain the sorting criteria and any special handling of edge cases.

9.6. Testing

Test your Comparator implementations thoroughly to ensure they sort the objects correctly under various scenarios.

10. Advanced Comparator Techniques

Advanced Comparator techniques involve using more sophisticated methods to achieve complex sorting requirements.

10.1. Chaining Comparators

Chaining Comparators involves combining multiple Comparators to sort objects based on multiple criteria.

10.1.1. Example: Chaining Comparators

import java.util.*;

class Student {
    String name;
    Integer age;

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }

    @Override
    public String toString() {
        return name + " : " + age;
    }
}

public class Main {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student("Ajay", 27));
        students.add(new Student("Sneha", 23));
        students.add(new Student("Simran", 37));
        students.add(new Student("Ankit", 22));
        students.add(new Student("Anshul", 29));
        students.add(new Student("Sneha", 22));

        Comparator<Student> nameComparator = Comparator.comparing(Student::getName);
        Comparator<Student> ageComparator = Comparator.comparing(Student::getAge);

        students.sort(nameComparator.thenComparing(ageComparator));

        System.out.println("After Sorting");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

In this example, the nameComparator and ageComparator are chained using the thenComparing() method to sort students first by name and then by age.

10.2. Using comparingInt, comparingLong, and comparingDouble

These methods provide a more efficient way to compare objects based on primitive types.

10.2.1. Example: Using comparingInt

import java.util.*;

class Student {
    String name;
    int age;

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return name + " : " + age;
    }
}

public class Main {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student("Ajay", 27));
        students.add(new Student("Sneha", 23));
        students.add(new Student("Simran", 37));
        students.add(new Student("Ankit", 22));

        students.sort(Comparator.comparingInt(Student::getAge));

        System.out.println("After Sorting");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

In this example, the comparingInt() method is used to compare students based on their ages, providing a more efficient way to compare primitive int values.

10.3. Using Custom Comparison Logic

You can use custom comparison logic within the compare() method to handle complex sorting requirements.

10.3.1. Example: Using Custom Comparison Logic

import java.util.*;

class Student {
    String name;
    Integer age;

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }

    @Override
    public String toString() {
        return name + " : " + age;
    }
}

public class Main {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student("Ajay", 27));
        students.add(new Student("Sneha", 23));
        students.add(new Student("Simran", 37));
        students.add(new Student("Ankit", 22));

        students.sort((s1, s2) -> {
            if (s1.getName().equals("Ajay")) {
                return -1; // Ajay should always be first
            } else if (s2.getName().equals("Ajay")) {
                return 1; // Ajay should always be first
            } else {
                return s1.getName().compareTo(s2.getName());
            }
        });

        System.out.println("After Sorting");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

In this example, custom comparison logic is used to ensure that the student named “Ajay” is always placed first in the sorted list.

10.4. Real-World Applications

These advanced techniques are valuable in scenarios where you need highly customized sorting strategies, such as sorting data based on complex business rules or prioritizing certain elements in a list.

11. Common Pitfalls to Avoid When Using Comparator

When working with Comparator in Java, it’s important to avoid common pitfalls that can lead to incorrect sorting or runtime errors.

11.1. Violating the Comparator Contract

The Comparator contract specifies that the compare() method must be consistent and transitive. Violating this contract can lead to unpredictable sorting behavior.

11.1.1. Example of Violating the Comparator Contract

import java.util.*;

class Student {
    String name;
    Integer age;

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }

    @Override
    public String toString() {
        return name + " : " + age;
    }
}

public class Main {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student("Ajay", 27));
        students.add(new Student("Sneha", 23));
        students.add(new Student("Simran", 37));
        students.add(new Student("Ankit", 22));

        Comparator<Student> brokenComparator = (s1, s2) -> {
            if (s1.getAge() > s2.getAge()) {
                return 1;
            } else if (s1.getAge() < s2.getAge()) {
                return -1;
            } else {
                return 0;
            }
        };

        // This comparator is not transitive because it doesn't handle equal ages consistently.

        students.sort(brokenComparator);

        System.out.println("After Sorting");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

In this example, the brokenComparator does not handle equal ages consistently, violating the transitivity requirement and leading to unpredictable sorting behavior.

11.2. Ignoring Edge Cases

Failing to handle edge cases, such as null values or empty collections, can lead to NullPointerExceptions or incorrect sorting results.

11.3. Overcomplicating the Comparison Logic

Overcomplicating the comparison logic can make the code harder to read and maintain, as well as potentially impacting performance.

11.4. Not Considering Performance Implications

Not considering the performance implications of the comparison logic can lead to slow sorting times, especially for large collections.

11.5. Improper Use of Lambda Expressions

While lambda expressions can make the code more concise, using them improperly can lead to confusion and errors. Ensure that the lambda expression is clear and easy to understand.

11.6. Neglecting Testing

Neglecting to test the Comparator implementation thoroughly can lead to undetected errors that can cause incorrect sorting behavior in production.

12. Real-World Examples of Comparator Usage

The Comparator interface is used extensively in various real-world applications to sort data based on specific criteria.

12.1. E-Commerce Applications

In e-commerce applications, Comparator is used to sort products based on price, rating, popularity, or other criteria.

12.1.1. Example: Sorting Products by Price


import java.util.*;

class Product {
    String name;
    double price;

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

    public String getName() {
        return name;
    }

    public double getPrice() {
        return price;
    }

    @Override
    public String toString() {
        return name + " : " + price;
    }
}

public class Main {
    public static void main(String[] args) {
        List<Product> products = new ArrayList<>();
        products.add(new

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 *