How Do I Use Comparable Interface In Java Effectively?

Comparable in Java is crucial for defining a natural order for objects of a user-defined class, especially when using collections and sorting. This article by compare.edu.vn explores the Comparable interface in Java, offering comprehensive guidance on its implementation, benefits, and real-world applications. It will help you understand how to use it to effectively sort and compare objects in your Java programs, leading to cleaner, more maintainable code. Let’s find out how it works, leveraging comparison methods, and optimizing sorting algorithms.

1. Understanding the Java Comparable Interface

The Comparable interface in Java, found in the java.lang package, allows you to define a natural ordering for objects. This is especially useful when you want to sort a collection of objects based on a specific criterion. By implementing the Comparable interface, your class gains the ability to be compared with other instances of the same class.

1.1. What is the Comparable Interface?

The Comparable interface mandates a single method, compareTo(), which dictates how objects of that class should be compared. This method allows you to specify whether one object is less than, equal to, or greater than another object. This natural ordering is fundamental for sorting algorithms and data structures that rely on comparisons.

1.2. Declaration of Comparable Interface

The declaration of the Comparable interface is straightforward:

public interface Comparable<T> {
    int compareTo(T obj);
}

Here, T represents the type of the object being compared. The compareTo() method should return:

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

1.3. Use of Comparable Interface

Implementing the Comparable interface involves the following steps:

  1. Implement the Comparable<T> interface in your class, where T is the type of your class.
  2. Override the compareTo(T obj) method to provide the comparison logic.
  3. Use Arrays.sort() or Collections.sort() to sort arrays or lists of your objects.

1.4. Benefits of Using Comparable

  • Natural Ordering: Defines a default way to compare objects, making sorting and searching more intuitive.
  • Integration with Java API: Works seamlessly with Java’s built-in sorting methods like Arrays.sort() and Collections.sort().
  • Code Readability: Enhances code readability by clearly defining how objects of a class relate to each other in terms of ordering.
  • Customizable: Allows you to customize the comparison logic based on specific attributes or criteria.

1.5. Limitations of Using Comparable

  • Single Ordering: Only one natural ordering can be defined per class.
  • Class Modification: Requires modification of the class to implement the interface, which might not be possible for library classes.
  • Limited Flexibility: Less flexible when you need multiple comparison strategies.

2. Implementing the Comparable Interface

To effectively use the Comparable interface, it’s essential to understand how to implement it correctly. This involves overriding the compareTo() method and defining the logic for comparing objects of your class.

2.1. Basic Implementation

Let’s start with a simple example of sorting integers using the Comparable interface:

import java.util.*;

class Number implements Comparable<Number> {
    int v; // Value of the number

    // Constructor
    public Number(int v) {
        this.v = v;
    }

    // toString() for displaying the number
    @Override
    public String toString() {
        return String.valueOf(v);
    }

    // compareTo() method to define sorting logic
    @Override
    public int compareTo(Number o) {
        // Ascending order
        return this.v - o.v;
    }

    public static void main(String[] args) {
        // Create an array of Number objects
        Number[] n = {new Number(4), new Number(1), new Number(7), new Number(2)};

        System.out.println("Before Sorting: " + Arrays.toString(n));

        // Sort the array
        Arrays.sort(n);

        // Display numbers after sorting
        System.out.println("After Sorting: " + Arrays.toString(n));
    }
}

Output:

Before Sorting: [4, 1, 7, 2]
After Sorting: [1, 2, 4, 7]

In this example, the compareTo() method is overridden to define the ascending order logic by comparing the v fields of Number objects. The Arrays.sort() method then sorts the array using this logic.

2.2. Sorting Strings

Here’s how to implement the Comparable interface to sort strings lexicographically:

import java.util.*;

class StringContainer implements Comparable<StringContainer> {
    String str;

    public StringContainer(String str) {
        this.str = str;
    }

    @Override
    public int compareTo(StringContainer other) {
        return this.str.compareTo(other.str);
    }

    @Override
    public String toString() {
        return str;
    }

    public static void main(String[] args) {
        StringContainer[] strings = {
            new StringContainer("banana"),
            new StringContainer("apple"),
            new StringContainer("cherry")
        };

        System.out.println("Before Sorting: " + Arrays.toString(strings));
        Arrays.sort(strings);
        System.out.println("After Sorting: " + Arrays.toString(strings));
    }
}

Output:

Before Sorting: [banana, apple, cherry]
After Sorting: [apple, banana, cherry]

This code defines a class StringContainer that implements Comparable<StringContainer>. The compareTo method uses the String.compareTo method to compare the strings lexicographically.

2.3. Sorting Dates

Here’s how to implement the Comparable interface to sort dates:

import java.util.Arrays;
import java.util.Date;

class Event implements Comparable<Event> {
    private Date eventDate;
    private String eventName;

    public Event(Date eventDate, String eventName) {
        this.eventDate = eventDate;
        this.eventName = eventName;
    }

    public Date getEventDate() {
        return eventDate;
    }

    public String getEventName() {
        return eventName;
    }

    @Override
    public int compareTo(Event otherEvent) {
        return this.eventDate.compareTo(otherEvent.eventDate);
    }

    @Override
    public String toString() {
        return "Event{" +
               "eventDate=" + eventDate +
               ", eventName='" + eventName + ''' +
               '}';
    }

    public static void main(String[] args) {
        Event[] events = new Event[3];
        events[0] = new Event(new Date(2024, 0, 15), "Launch");
        events[1] = new Event(new Date(2024, 0, 1), "Meeting");
        events[2] = new Event(new Date(2024, 0, 20), "Party");

        System.out.println("Before Sorting: " + Arrays.toString(events));
        Arrays.sort(events);
        System.out.println("After Sorting: " + Arrays.toString(events));
    }
}

Output:

Before Sorting: [Event{eventDate=Sun Jan 15 00:00:00 PST 3924, eventName='Launch'}, Event{eventDate=Tue Jan 01 00:00:00 PST 3924, eventName='Meeting'}, Event{eventDate=Fri Jan 20 00:00:00 PST 3924, eventName='Party'}]
After Sorting: [Event{eventDate=Tue Jan 01 00:00:00 PST 3924, eventName='Meeting'}, Event{eventDate=Sun Jan 15 00:00:00 PST 3924, eventName='Launch'}, Event{eventDate=Fri Jan 20 00:00:00 PST 3924, eventName='Party'}]

This code defines a class Event that implements Comparable<Event>. The compareTo method uses the Date.compareTo method to compare the event dates.

2.4. Sorting Custom Objects

Consider a scenario where you have a class representing a Student with attributes like name and age. You can implement Comparable to sort students based on their age:

import java.util.*;

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

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

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

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

    public static void main(String[] args) {
        Student[] students = {
            new Student("Alice", 20),
            new Student("Bob", 18),
            new Student("Charlie", 22)
        };

        System.out.println("Before Sorting: " + Arrays.toString(students));
        Arrays.sort(students);
        System.out.println("After Sorting: " + Arrays.toString(students));
    }
}

Output:

Before Sorting: [Alice (20), Bob (18), Charlie (22)]
After Sorting: [Bob (18), Alice (20), Charlie (22)]

In this example, students are sorted in ascending order based on their age.

2.5. Complex Sorting Logic

You can also implement more complex sorting logic. For instance, you might want to sort Student objects first by age and then by name if the ages are the same:

import java.util.*;

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

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

    @Override
    public int compareTo(Student other) {
        if (this.age != other.age) {
            return this.age - other.age;
        } else {
            return this.name.compareTo(other.name);
        }
    }

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

    public static void main(String[] args) {
        Student[] students = {
            new Student("Alice", 20),
            new Student("Bob", 18),
            new Student("Charlie", 20)
        };

        System.out.println("Before Sorting: " + Arrays.toString(students));
        Arrays.sort(students);
        System.out.println("After Sorting: " + Arrays.toString(students));
    }
}

Output:

Before Sorting: [Alice (20), Bob (18), Charlie (20)]
After Sorting: [Bob (18), Alice (20), Charlie (20)]

Here, the compareTo() method first compares the ages. If the ages are different, it returns the result of the age comparison. If the ages are the same, it compares the names lexicographically.

2.6. Considerations for Implementing CompareTo

  • Consistency with Equals: Ensure that your compareTo() method is consistent with the equals() method. If two objects are equal according to equals(), their compareTo() method should return 0.
  • Null Handling: Handle null values appropriately to avoid NullPointerException.
  • Transitivity: Ensure that your comparison logic is transitive. If a > b and b > c, then a > c must also be true.

3. Advanced Usage of Comparable

Beyond basic sorting, the Comparable interface can be used in more advanced scenarios, such as sorting complex data structures and integrating with other Java APIs.

3.1. Sorting Lists and Collections

The Collections.sort() method can be used to sort lists of objects that implement the Comparable interface:

import java.util.*;

class Book implements Comparable<Book> {
    String title;
    String author;
    int year;

    public Book(String title, String author, int year) {
        this.title = title;
        this.author = author;
        this.year = year;
    }

    @Override
    public int compareTo(Book other) {
        return this.title.compareTo(other.title);
    }

    @Override
    public String toString() {
        return title + " by " + author + " (" + year + ")";
    }

    public static void main(String[] args) {
        List<Book> books = new ArrayList<>();
        books.add(new Book("The Great Gatsby", "F. Scott Fitzgerald", 1925));
        books.add(new Book("To Kill a Mockingbird", "Harper Lee", 1960));
        books.add(new Book("1984", "George Orwell", 1949));

        System.out.println("Before Sorting: " + books);
        Collections.sort(books);
        System.out.println("After Sorting: " + books);
    }
}

Output:

Before Sorting: [The Great Gatsby by F. Scott Fitzgerald (1925), To Kill a Mockingbird by Harper Lee (1960), 1984 by George Orwell (1949)]
After Sorting: [1984 by George Orwell (1949), The Great Gatsby by F. Scott Fitzgerald (1925), To Kill a Mockingbird by Harper Lee (1960)]

This example demonstrates how to sort a list of Book objects by title using Collections.sort().

3.2. Using Comparable with TreeSet and TreeMap

The TreeSet and TreeMap classes automatically sort elements based on their natural ordering, provided that the elements implement the Comparable interface.

import java.util.*;

class Person implements Comparable<Person> {
    String name;
    int age;

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

    @Override
    public int compareTo(Person other) {
        return Integer.compare(this.age, other.age);
    }

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

    public static void main(String[] args) {
        TreeSet<Person> people = new TreeSet<>();
        people.add(new Person("Alice", 25));
        people.add(new Person("Bob", 30));
        people.add(new Person("Charlie", 20));

        System.out.println("Sorted Set: " + people);
    }
}

Output:

Sorted Set: [Charlie (20), Alice (25), Bob (30)]

In this example, the TreeSet automatically sorts the Person objects by age due to the implementation of the Comparable interface.

3.3. Sorting with Multiple Criteria

In some cases, you might need to sort objects based on multiple criteria. This can be achieved by implementing a more complex compareTo() method:

import java.util.*;

class Product implements Comparable<Product> {
    String name;
    double price;
    int quantity;

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

    @Override
    public int compareTo(Product other) {
        // Sort by price in ascending order
        int priceComparison = Double.compare(this.price, other.price);
        if (priceComparison != 0) {
            return priceComparison;
        }

        // If prices are the same, sort by quantity in descending order
        return Integer.compare(other.quantity, this.quantity);
    }

    @Override
    public String toString() {
        return name + " ($" + price + ", " + quantity + " units)";
    }

    public static void main(String[] args) {
        List<Product> products = new ArrayList<>();
        products.add(new Product("Laptop", 1200.00, 5));
        products.add(new Product("Keyboard", 75.00, 50));
        products.add(new Product("Mouse", 25.00, 100));
        products.add(new Product("Monitor", 300.00, 20));
        products.add(new Product("Tablet", 300.00, 15));

        System.out.println("Before Sorting: " + products);
        Collections.sort(products);
        System.out.println("After Sorting: " + products);
    }
}

Output:

Before Sorting: [Laptop ($1200.0, 5 units), Keyboard ($75.0, 50 units), Mouse ($25.0, 100 units), Monitor ($300.0, 20 units), Tablet ($300.0, 15 units)]
After Sorting: [Mouse ($25.0, 100 units), Keyboard ($75.0, 50 units), Tablet ($300.0, 15 units), Monitor ($300.0, 20 units), Laptop ($1200.0, 5 units)]

In this example, products are first sorted by price in ascending order. If the prices are the same, they are then sorted by quantity in descending order.

3.4. Using Comparable with Legacy Code

When working with legacy code, you might encounter classes that do not implement the Comparable interface. In such cases, you can use a Comparator to define a custom comparison logic without modifying the original class.

4. Comparable vs. Comparator

While Comparable provides a natural ordering for objects, Comparator offers an alternative approach for defining comparison logic. Understanding the differences between these two interfaces is crucial for effective Java programming.

4.1. Key Differences

  • Comparable:
    • Defines a natural ordering for a class.
    • Requires the class to implement the interface.
    • Provides a single comparison logic.
  • Comparator:
    • Defines a custom ordering for a class.
    • Does not require the class to implement any interface.
    • Allows multiple comparison logics.

4.2. When to Use Comparable

  • When you want to define a default comparison logic for a class.
  • When you have control over the class and can modify it.
  • When you need to integrate with Java’s built-in sorting methods that rely on natural ordering.

4.3. When to Use Comparator

  • When you need multiple comparison logics for a class.
  • When you don’t have control over the class and cannot modify it.
  • When you need to sort objects based on different criteria at different times.

4.4. Implementing Comparator

Here’s an example of using a Comparator to sort Student objects by name:

import java.util.*;

class Student {
    String name;
    int age;

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

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

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

public class Main {
    public static void main(String[] args) {
        Student[] students = {
            new Student("Alice", 20),
            new Student("Bob", 18),
            new Student("Charlie", 22)
        };

        System.out.println("Before Sorting: " + Arrays.toString(students));
        Arrays.sort(students, new SortByName());
        System.out.println("After Sorting: " + Arrays.toString(students));
    }
}

Output:

Before Sorting: [Alice (20), Bob (18), Charlie (22)]
After Sorting: [Alice (20), Bob (18), Charlie (22)]

In this example, the SortByName class implements the Comparator<Student> interface and provides a custom comparison logic based on the name attribute.

4.5. Combining Comparable and Comparator

You can use both Comparable and Comparator in the same class. The Comparable interface defines the natural ordering, while the Comparator provides additional custom orderings.

5. Best Practices for Using Comparable

To ensure that you use the Comparable interface effectively, follow these best practices:

5.1. Implement Consistently with Equals

Ensure that your compareTo() method is consistent with the equals() method. If two objects are equal according to equals(), their compareTo() method should return 0. This is crucial for maintaining consistency and avoiding unexpected behavior in data structures like TreeSet and TreeMap.

5.2. Handle Null Values

Handle null values appropriately to avoid NullPointerException. You can either throw an exception or define a specific ordering for null values. For example, you might consider null values to be either the smallest or the largest elements.

5.3. Ensure Transitivity

Ensure that your comparison logic is transitive. If a > b and b > c, then a > c must also be true. Violating transitivity can lead to unpredictable sorting results and can break the contract of the Comparable interface.

5.4. Use Integer.compare and Double.compare

Use Integer.compare() and Double.compare() for comparing primitive types. These methods handle potential overflow issues and provide a more robust comparison than simple subtraction.

5.5. Document Your Comparison Logic

Document your comparison logic clearly in the compareTo() method. Explain the criteria used for comparison and any specific considerations or edge cases. This will help other developers understand and maintain your code.

6. Common Mistakes to Avoid

When working with the Comparable interface, avoid these common mistakes:

6.1. Inconsistent Comparison

Avoid implementing a compareTo() method that is inconsistent with the equals() method. This can lead to unexpected behavior in data structures and sorting algorithms.

6.2. Ignoring Overflow Issues

Be careful when using subtraction to compare integers, as it can lead to overflow issues. Use Integer.compare() instead.

6.3. Not Handling Null Values

Failing to handle null values can result in NullPointerException. Always check for null values and handle them appropriately.

6.4. Violating Transitivity

Ensure that your comparison logic is transitive. Violating transitivity can lead to unpredictable sorting results.

6.5. Poor Documentation

Failing to document your comparison logic can make it difficult for other developers to understand and maintain your code. Always document your compareTo() method clearly.

7. Real-World Examples

Let’s explore some real-world examples of using the Comparable interface:

7.1. Sorting a List of Employees

Consider a scenario where you have a list of Employee objects and you want to sort them based on their salary:

import java.util.*;

class Employee implements Comparable<Employee> {
    String name;
    double salary;

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

    @Override
    public int compareTo(Employee other) {
        return Double.compare(this.salary, other.salary);
    }

    @Override
    public String toString() {
        return name + " ($" + salary + ")";
    }

    public static void main(String[] args) {
        List<Employee> employees = new ArrayList<>();
        employees.add(new Employee("Alice", 50000.00));
        employees.add(new Employee("Bob", 60000.00));
        employees.add(new Employee("Charlie", 40000.00));

        System.out.println("Before Sorting: " + employees);
        Collections.sort(employees);
        System.out.println("After Sorting: " + employees);
    }
}

Output:

Before Sorting: [Alice ($50000.0), Bob ($60000.0), Charlie ($40000.0)]
After Sorting: [Charlie ($40000.0), Alice ($50000.0), Bob ($60000.0)]

7.2. Sorting a List of Products by Price

In an e-commerce application, you might want to sort a list of products by their price:

import java.util.*;

class Product implements Comparable<Product> {
    String name;
    double price;

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

    @Override
    public int compareTo(Product other) {
        return Double.compare(this.price, other.price);
    }

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

    public static void main(String[] args) {
        List<Product> products = new ArrayList<>();
        products.add(new Product("Laptop", 1200.00));
        products.add(new Product("Keyboard", 75.00));
        products.add(new Product("Mouse", 25.00));

        System.out.println("Before Sorting: " + products);
        Collections.sort(products);
        System.out.println("After Sorting: " + products);
    }
}

Output:

Before Sorting: [Laptop ($1200.0), Keyboard ($75.0), Mouse ($25.0)]
After Sorting: [Mouse ($25.0), Keyboard ($75.0), Laptop ($1200.0)]

7.3. Sorting a List of Dates

In a calendar application, you might want to sort a list of events by their dates:

import java.util.*;
import java.util.Date;

class Event implements Comparable<Event> {
    String name;
    Date date;

    public Event(String name, Date date) {
        this.name = name;
        this.date = date;
    }

    @Override
    public int compareTo(Event other) {
        return this.date.compareTo(other.date);
    }

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

    public static void main(String[] args) {
        List<Event> events = new ArrayList<>();
        events.add(new Event("Meeting", new Date(2024, 0, 15)));
        events.add(new Event("Conference", new Date(2024, 0, 10)));
        events.add(new Event("Workshop", new Date(2024, 0, 20)));

        System.out.println("Before Sorting: " + events);
        Collections.sort(events);
        System.out.println("After Sorting: " + events);
    }
}

Output:

Before Sorting: [Meeting (Sun Jan 15 00:00:00 PST 3924), Conference (Fri Jan 10 00:00:00 PST 3924), Workshop (Fri Jan 20 00:00:00 PST 3924)]
After Sorting: [Conference (Fri Jan 10 00:00:00 PST 3924), Meeting (Sun Jan 15 00:00:00 PST 3924), Workshop (Fri Jan 20 00:00:00 PST 3924)]

8. Performance Considerations

When using the Comparable interface, it’s essential to consider the performance implications of your comparison logic.

8.1. Complexity of CompareTo Method

The complexity of your compareTo() method can significantly impact the performance of sorting algorithms. Aim for a compareTo() method with O(1) complexity, especially for large datasets.

8.2. Sorting Algorithms

Java’s Arrays.sort() and Collections.sort() methods use efficient sorting algorithms like quicksort and mergesort, which have an average time complexity of O(n log n). However, the actual performance can vary depending on the data and the implementation of the compareTo() method.

8.3. Caching Comparison Results

If your comparison logic involves expensive calculations, consider caching the results to improve performance. This can be particularly useful when sorting large datasets.

8.4. Using Comparators for Optimized Sorting

In some cases, using a Comparator can provide better performance than relying on the Comparable interface. Comparators allow you to define custom comparison logics that are optimized for specific scenarios.

9. Use Cases for Comparable

The Comparable interface is versatile and can be applied in various use cases:

9.1. Data Sorting

Sorting data based on a specific attribute, such as sorting a list of products by price or a list of employees by salary.

9.2. Custom Data Structures

Implementing custom data structures that require elements to be sorted, such as a sorted linked list or a sorted binary tree.

9.3. Searching and Filtering

Searching and filtering data based on a specific criterion, such as finding the smallest or largest element in a collection.

9.4. Data Validation

Validating data to ensure that it meets certain criteria, such as ensuring that dates are in chronological order or that prices are within a certain range.

9.5. Data Analysis

Analyzing data to identify trends and patterns, such as identifying the most popular products or the highest-paid employees.

10. Examples of How to Sort Different Data Types Using Comparable

The Comparable interface is a fundamental part of Java that allows developers to define a natural ordering for objects. This is particularly useful when sorting collections of custom objects. Here’s how you can sort different data types using Comparable:

10.1. Sorting Integers

Sorting a list of integers can be achieved using the Comparable interface in a custom class that wraps the integer value:

import java.util.*;

class IntContainer implements Comparable<IntContainer> {
    private int value;

    public IntContainer(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    @Override
    public int compareTo(IntContainer other) {
        return Integer.compare(this.value, other.value);
    }

    @Override
    public String toString() {
        return String.valueOf(value);
    }

    public static void main(String[] args) {
        List<IntContainer> numbers = new ArrayList<>();
        numbers.add(new IntContainer(5));
        numbers.add(new IntContainer(1));
        numbers.add(new IntContainer(10));
        numbers.add(new IntContainer(3));

        System.out.println("Before sorting: " + numbers);
        Collections.sort(numbers);
        System.out.println("After sorting: " + numbers);
    }
}

Output:

Before sorting: [5, 1, 10, 3]
After sorting: [1, 3, 5, 10]

10.2. Sorting Strings Lexicographically

Strings can be sorted lexicographically by encapsulating them in a class that implements Comparable:

import java.util.*;

class StringContainer implements Comparable<StringContainer> {
    private String value;

    public StringContainer(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    @Override
    public int compareTo(StringContainer other) {
        return this.value.compareTo(other.getValue());
    }

    @Override
    public String toString() {
        return value;
    }

    public static void main(String[] args) {
        List<StringContainer> strings = new ArrayList<>();
        strings.add(new StringContainer("banana"));
        strings.add(new StringContainer("apple"));
        strings.add(new StringContainer("cherry"));

        System.out.println("Before sorting: " + strings);
        Collections.sort(strings);
        System.out.println("After sorting: " + strings);
    }
}

Output:

Before sorting: [banana, apple, cherry]
After sorting: [apple, banana, cherry]

10.3. Sorting Dates

Dates can be sorted by wrapping the Date object in a custom class and using the compareTo method of the Date class:

import java.util.*;
import java.util.Date;

class DateContainer implements Comparable<DateContainer> {
    private Date date;
    private String eventName;

    public DateContainer(Date date, String eventName) {
        this.date = date;
        this.eventName = eventName;
    }

    public Date getDate() {
        return date;
    }

    @Override
    public int compareTo(DateContainer other) {
        return this.date.compareTo(other.getDate());
    }

    @Override
    public String toString() {
        return eventName + " (" + date + ")";
    }

    public static void main(String[] args) {
        List<DateContainer> dates = new ArrayList<>();
        dates.add(new DateContainer(new Date(2024, 0, 15), "Launch"));
        dates.add(new DateContainer(new Date(2024, 0, 1), "Meeting"));
        dates.add(new DateContainer(new Date(2024, 0, 20), "Party"));

        System.out.println("Before sorting: " + dates);
        Collections.sort(dates);
        System.out.println("After sorting: " + dates);
    }
}

Output:


Before sorting: [Launch (Sun Jan 15 00:00:00 PST 3924), Meeting (Tue Jan 01 00:00:

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 *