Java Basics

Comparable Java Example

In this tutorial, we will discuss Java comparable objects. Java provides the Comparator interface and the Comparable interface, which contains only one method, called compareTo. This method compares two objects, to impose an order between them. Specifically, it returns a negative integer, zero, or a positive integer to indicate that the input object is less than, equal to or greater than the existing object.

1. The Comparable Interface

Java provides the Comparator interface, which contains two methods, called compare and equals. The first method compares its two input arguments and imposes an order between them. It returns a negative integer, zero, or a positive integer to indicate that the first argument is less than, equal to, or greater than the second. The second method requires an Object as a parameter and aims to decide whether the input object is equal to the comparator. The method returns true, only if the specified object is also a comparator and it imposes the same ordering as the comparator.

java comparable interface

The Java Comparable interface is mainly used to sort the arrays or lists of custom objects. Lists and arrays of objects that implement the Java Comparable interface can be sorted automatically by Collections.sort() and Arrays.sort().

Let’s see how we can sort elements of arrays and lists containing wrapper classes objects that already implements the Java Comparable interface.

Sorting arrays and lists with warpper class elements

//Sorting array of integers using Arrays.sort()
int[] arr = {8, 5, 1, 4, 7, 9, 2, 3, 6, 0};
System.out.println("Integer array before sorting: " + Arrays.toString(arr));
Arrays.sort(arr);
System.out.println("Integer array after sorting: " + Arrays.toString(arr));

//Sorting array of Strings using Arrays.sort()
String[] names = {"Pat", "Lesa", "Jackie", "Charles"};
System.out.println("String array before sorting: " + Arrays.toString(names));
Arrays.sort(names);
System.out.println("String array after sorting: " + Arrays.toString(names));

//Sorting List of String Collections.sort()
List<String> fruits = Arrays.asList("Orange", "Banana", "Apple", "Guava", "Grapes");
System.out.println("String list before sorting: " + fruits);
Collections.sort(fruits);
System.out.println("String list after sorting: " + fruits);

output

Integer array before sorting: [8, 5, 1, 4, 7, 9, 2, 3, 6, 0]
Integer array after sorting: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
String array before sorting: [Pat, Lesa, Jackie, Charles]
String array after sorting: [Charles, Jackie, Lesa, Pat]
String list before sorting: [Orange, Banana, Apple, Guava, Grapes]
String list after sorting: [Apple, Banana, Grapes, Guava, Orange]

Since all wrapper classes already implement the Java Comparable Interface and provided a default implementation of compareTo() the method, that is why we can use Collections.sort() and Arrays.sort() on these objects.

If we wanted to sort a user-defined class let’s say Employee class into some specific order we have to implement the Comparable interface and provide the implementation of its compareTo() method. Comparable interface present into java.lang package. By using the Comparable interface we can define only one way to sort element of Arrays or List containing the user-defined class.

1.1 The compareTo() of Comparable Interface in Java

This method compares the current object and the object which has been passed and returns-

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

The declaration of compareTo() looks like below in Comparable interface-

int compareTo(T o)

The above method also throws NullPointerException or ClassCastException if the specified object is null or if the specified object’s type prevents it from being compared to this object.

Now let’s use Comparable one our defined Employee class and provide the implementation of compareTo() method to sort its elements based on their first name.

The Employee class

class Employee implements Comparable {

    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;
    }

    @Override
    public int compareTo(Employee employee) {
        return this.name.compareTo(employee.name);
    }

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

Now, let’s use this Employee class with array and list to sort them-

Sorting Employee elements

//Sorting array of Employee objects using Arrays.sort()
Employee[] employees = {new Employee(1, "Pat", 1000.0),
        new Employee(2, "Lesa", 2500.0),
        new Employee(3, "Jackie", 1500.0),
        new Employee(4, "Charles", 6000.0)};
System.out.println("Employee array before sorting: " + Arrays.toString(employees));
Arrays.sort(employees);
System.out.println("Employee array after sorting: " + Arrays.toString(employees));

//Sorting List of Employee objects Collections.sort()
List employeeList = Arrays.asList(new Employee(1, "Pat", 1000.0),
        new Employee(2, "Lesa", 2500.0),
        new Employee(3, "Jackie", 1500.0),
        new Employee(4, "Charles", 6000.0));
System.out.println("Employee list before sorting: " + employeeList);
Arrays.sort(employees);
System.out.println("Employee list after sorting: " + employeeList);

Here in this code, first we created an array of Employee objects and then sorted them using Arrays.sort() method. Again we created a list of same employee objects and used Collections.sort() to sort them. Finally, here is the output-

Output

Employee array before sorting: [Employee{id=1, name='Pat', salary=1000.0}, Employee{id=2, name='Lesa', salary=2500.0}, Employee{id=3, name='Jackie', salary=1500.0}, Employee{id=4, name='Charles', salary=6000.0}]
Employee array after sorting: [Employee{id=4, name='Charles', salary=6000.0}, Employee{id=3, name='Jackie', salary=1500.0}, Employee{id=2, name='Lesa', salary=2500.0}, Employee{id=1, name='Pat', salary=1000.0}]
Employee list before sorting: [Employee{id=1, name='Pat', salary=1000.0}, Employee{id=2, name='Lesa', salary=2500.0}, Employee{id=3, name='Jackie', salary=1500.0}, Employee{id=4, name='Charles', salary=6000.0}]
Employee list after sorting: [Employee{id=1, name='Pat', salary=1000.0}, Employee{id=2, name='Lesa', salary=2500.0}, Employee{id=3, name='Jackie', salary=1500.0}, Employee{id=4, name='Charles', salary=6000.0}]

2. The Comparator Java Interface

One of the limitations of sorting using Comparable interface is that it gives only one way to sort the elements of arrays or collections. If we wanted to have multiple choices Comparable interface doesn’t give a way to do this.

If we wanted to have multiple choices for sorting a given collection or array element, we would have to write multiple Comparator Java classes implementing Comparator interface and providing an implementation of it compare() method. We can pass a comparator Java class as the second argument to Collections.sort() and Arrays.sort() to use respective sorting logic.

2.1 The compare() of Comparator Interface in Java

This method compares the first object with the object and returns-

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

The declaration of compare() looks like below in Comparator interface-

int compare(T o1, T o2)

The above method also throws NullPointerException or ClassCastException if the specified object is null or if the specified object’s type prevents it from being compared to this object.

Now, let’s write Comparator for the same Employee class to sort it by using name and salary. We will write EmployeeNameComparator and EmployeeSalaryComparator to do the sorting. Now let’s write the two comparator classes-

EmployeeNameComparator.java

package com.javacodegeeks.examples.comparable;

import java.util.Comparator;

class EmployeeNameComparator implements Comparator<Employee> {
    @Override
    public int compare(Employee e1, Employee e2) {
        return e1.getName().compareTo(e2.getName());
    }
}

EmployeeSalaryComparator.java

package com.javacodegeeks.examples.comparable;

import java.util.Comparator;

public class EmployeeSalaryComparator implements Comparator<Employee> {

    @Override
    public int compare(Employee e1, Employee e2) {
        return e1.getSalary().compareTo(e2.getSalary());
    }
}

Now, let’s use these comparators in our code to sort Employee array and list based on name and salary-

Using EmployeeNameComparator with Employee objects

     
//Sorting array of Employee objects by their name using Arrays.sort()
Employee[] employees = {new Employee(1, "Pat", 1000.0),
        new Employee(2, "Lesa", 2500.0),
        new Employee(3, "Jackie", 1500.0),
        new Employee(4, "Charles", 6000.0)};
System.out.println("Employee array before sorting: " + Arrays.toString(employees));
Arrays.sort(employees, new EmployeeNameComparator());
System.out.println("Employee array after sorting by name: " + Arrays.toString(employees));

//Sorting List of Employee objects by their name Collections.sort()
List employeeList = Arrays.asList(new Employee(1, "Pat", 1000.0),
        new Employee(2, "Lesa", 2500.0),
        new Employee(3, "Jackie", 1500.0),
        new Employee(4, "Charles", 6000.0));
System.out.println("Employee list before sorting: " + employeeList);
Collections.sort(employeeList, new EmployeeNameComparator());
System.out.println("Employee list after sorting by name: " + employeeList);

In the above code, we used EmployeeNameComparator to sort Employee array and employee list based on their names. Here is the output of above code.

Output

  
Employee array before sorting: [Employee{id=1, name='Pat', salary=1000.0}, Employee{id=2, name='Lesa', salary=2500.0}, Employee{id=3, name='Jackie', salary=1500.0}, Employee{id=4, name='Charles', salary=6000.0}]
Employee array after sorting by name: [Employee{id=4, name='Charles', salary=6000.0}, Employee{id=3, name='Jackie', salary=1500.0}, Employee{id=2, name='Lesa', salary=2500.0}, Employee{id=1, name='Pat', salary=1000.0}]
Employee list before sorting: [Employee{id=1, name='Pat', salary=1000.0}, Employee{id=2, name='Lesa', salary=2500.0}, Employee{id=3, name='Jackie', salary=1500.0}, Employee{id=4, name='Charles', salary=6000.0}]
Employee list after sorting by name: [Employee{id=4, name='Charles', salary=6000.0}, Employee{id=3, name='Jackie', salary=1500.0}, Employee{id=2, name='Lesa', salary=2500.0}, Employee{id=1, name='Pat', salary=1000.0}]

Now, let’s use EmployeeSalaryComparator with Employee objects.

Using EmployeeSalaryComparator with Employee objects

        
//Sorting array of Employee objects by their salary using Arrays.sort()
Employee[] employees = {new Employee(1, "Pat", 1000.0),
        new Employee(2, "Lesa", 2500.0),
        new Employee(3, "Jackie", 1500.0),
        new Employee(4, "Charles", 6000.0)};
System.out.println("Employee array before sorting: " + Arrays.toString(employees));
Arrays.sort(employees, new EmployeeSalaryComparator());
System.out.println("Employee array after sorting by salary: " + Arrays.toString(employees));

//Sorting List of Employee objects by their salary Collections.sort()
List employeeList = Arrays.asList(new Employee(1, "Pat", 1000.0),
        new Employee(2, "Lesa", 2500.0),
        new Employee(3, "Jackie", 1500.0),
        new Employee(4, "Charles", 6000.0));
System.out.println("Employee list before sorting: " + employeeList);
Collections.sort(employeeList, new EmployeeSalaryComparator());
System.out.println("Employee list after sorting by salary: " + employeeList);

In the above code, we used EmployeeSalaryComparator to sort Employee array and employee list based on their salary. Here is the output of above code.

Output

 
Employee array before sorting: [Employee{id=1, name='Pat', salary=1000.0}, Employee{id=2, name='Lesa', salary=2500.0}, Employee{id=3, name='Jackie', salary=1500.0}, Employee{id=4, name='Charles', salary=6000.0}]
Employee array after sorting by salary: [Employee{id=1, name='Pat', salary=1000.0}, Employee{id=3, name='Jackie', salary=1500.0}, Employee{id=2, name='Lesa', salary=2500.0}, Employee{id=4, name='Charles', salary=6000.0}]
Employee list before sorting: [Employee{id=1, name='Pat', salary=1000.0}, Employee{id=2, name='Lesa', salary=2500.0}, Employee{id=3, name='Jackie', salary=1500.0}, Employee{id=4, name='Charles', salary=6000.0}]
Employee list after sorting by salary: [Employee{id=1, name='Pat', salary=1000.0}, Employee{id=3, name='Jackie', salary=1500.0}, Employee{id=2, name='Lesa', salary=2500.0}, Employee{id=4, name='Charles', salary=6000.0}] 

3. Difference between Comparable and Comparator Interfaces

Below table shows a comparison between implementing sorting logic by using Comparable and Comparator interfaces-

PropertyComparableComparator
Sort
Order
Comparable provides a single sorting order. In other words, we can sort the collection by using only one logic also called default or natural sorting orderThe Comparator provides multiple sorting order. In other words, we can sort the collection by using multiple logic passed at run time. It is also known as custom sorting order.
Modify ClassesTo implement Comparable we have to change the existing class on which we have to implement sorting logicTo implement Comparator we don’t require any change to existing class on which we have to implement sorting logic
Method to implementIt provides the compareTo() method with one argument to sort elements of array or collections.It provides the compare() method with two arguments to sort elements of array or collections.
Logical DifferenceLogically, Comparable is meant for objects with natural ordering which means the object itself must know how it is to be ordered.Comparator is meant for objects with custom order which means the object never knows how it is to be ordered. 
Objects needed for ComparisionComparable interface compares current reference with the object passed in argument.Comparator interface compares two different objects passed as arguments.
Method to useWe can sort the list elements of Comparable type by Collections.sort(List) method.We can sort the list elements of Comparator type by Collections.sort(List, Comparator) method.
packageComparable interface is in java.lang packageComparable interface is in java.util package

4. When to use Comparable and Comparator

1. We should use the Comparable interface if a default way of sorting Object already exists during the development of the class. For Example, String class objects should be sorted alphabetically and Employee class objects should be sorted by their ids. On the other hand, we should use the Comparator interface if an object can be sorted in multiple ways. For example, The Employee class object can be sorted by its name or salary.

2. Sometimes we are not able to write to the original class or we don’t have access to it. In these situations, since we can’t implement Comparable, Comparator is the only way to sort those objects.

3. If we want the object to be stored in SortedSet or SortedMap like TreeSet and TreeMap and it doesn’t implement Comparable then before putting them into SortedMap or TreeMap, we should always provide the corresponding Comparator which provides sorting logic.

4. We should not ignore the order of comparison while implementing Comparable or Comparator interface. For example, if we are sorting an object based on the name, we can compare the first name or last name in any order. So decide carefully.

5. The comparator has the advantage of being self-descriptive. For example, if we are writing a Comparator to compare two Employees by their salaries then we could name that comparator SalaryComparator.On the other hand, compareTo() doesn’t have any specific way to indicate its sorting criteria.

5. Conclusion

So in summary, if you want to sort objects based on natural order with one sorting logic then use Comparable in Java. If you want to sort on some custom logic with more than one sorting criterion then go for Comparator in Java.

6. Download the Source Code

That was all about Java Comparable example. Hope you enjoyed it.

Download
You can download the full source code of this example here: Comparable Java Example

Last updated on Aug. 27, 2019

Sotirios-Efstathios Maneas

Sotirios-Efstathios (Stathis) Maneas is a PhD student at the Department of Computer Science at the University of Toronto. His main interests include distributed systems, storage systems, file systems, and operating systems.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
SHIKHAR CHOUDHARY
SHIKHAR CHOUDHARY
6 years ago

In the above example when you have implemented comparable you didn’t give what type this comparable will be so the code will give compile time error.As, when you will see the implementation of comparable in java you will find it is a generic interface that means when we implement comparable we have to genrify it with the person class.
like this:-
class Person implements Comparable
and not like this
class Person implements Comparable

Back to top button