A comparator is an interface in Java, which comes under java.util package. It is used to sort the collection of objects.

To compare the set of elements in an object, the comparator provides multiple sorting sequences. Hence we can sort the objects based on any property.

Syntax:

public int compare(Object o1,Object o2);

This method compares the two arguments(objects) given and returns any one of the following values depending upon 3 cases:

  • Firstly, if the first element is less than the second element it returns “-1″.
  • In the case that the first element equals to the second element, it returns “0”.
  • The last case in which the first element is greater than the second element, it returns “1”.

Unlike the Comparable Interface, a class whose objects are to be sorted does not implement the Comparator interface. Rather, some third class can include this interface for sorting.

Note: Click here to know about the Comparable in Java.

 

Comparator Example

For instance, here, the “City” class need to implement Comparable to indicate the group of city objects via its ID. While in Comparator Interface, a class whose objects need to be sorted doesn’t implement this interface. Whereas other class can implement this interface like CityComparator. Let us look into the example.

For example, firstly, let us create a class “City”, and define the objects of that class.

City.java
class City{
    int id;
    String city;
    public City(int id, String city) {
        this.id = id;
        this.city = city;
    }
}

Now let us create another class CityComparator which implements the Comparator interface to provide the bean comparison mechanism.

CityComparator.java
class CityComparator implements Comparator<City> {
    @Override
    public int compare(City o1, City o2) {
        if (o1.id == o2.id) {
            return 0;
        } else if (o1.id > o2.id) {
            return 1;
        } else {
            return -1;
        }
    }
}

It is time to create the ComparatorDemo class from which we can access the City class.

ComparatorDemo.java
public class ComparatorDemo {
    public static void main(String[] args) {
        List<City> l = new ArrayList<City>();
        l.add(new City(1, "Vijayawada"));
        l.add(new City(5, "Mumbai"));
        l.add(new City(4, "Visakhapatnam"));
        l.add(new City(2, "Delhi"));
        int size = l.size();
        System.out.println("Before Comparator");
        for (int i = 0; i < size; i++) {
            City city = l.get(i);
            System.out.print(city.id + " ");
            System.out.print(city.city + " ");
        }
        System.out.println("\n After Comparator");
        Collections.sort(l, new CityComparator());
        System.out.println("");
        for (int i = 0; i < size; i++) {
            City city = l.get(i);
            System.out.print(city.id + " ");
            System.out.print(city.city + " ");
        }
    }
}

Output:

Terminal
Before Comparator
1 Vijayawada 5 Mumbai 4 Visakhapatnam 2 Delhi
After Comparator
1 Vijayawada
2 Delhi
4 Visakhapatnam
5 Mumbai

Comparing Two Different Beans

The main advantage of the Comparator is, it compares two bean properties. Hence we can compare two different beans using the Comparator interface, but both should be the same type. The below example compares the Cat Object with Elephant Object and checks if both are Animal Type.

Firstly, let us create a class “Animal” which implements the Comparator interface.

Animal.java
import java.util.Comparator;
public class Animal implements Comparable<Animal> {
    private int id;
    private String name;
    public Animal() {
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public int compareTo(Animal animal) {
        int result = 0;
        try {
            if (getId() < animal.getId()) {
                result = -1;
            } else if (getId() == animal.getId()) {
                result = 0;
            } else {
                result = 1;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}

Now, let’s create the Cat and Elephant classes. Here I am not implementing any methods. Because I am using dynamic method dispatch (Assigning the subclass object to superclass reference).

public class Cat extends Animal {
}
public class Elephant extends Animal {
}

Let us create SortDemo.java, to access the Animal Object.

SortDemo.java
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
class SortDemo {
    public static void main(String[] args) {
        List<Animal> animal_list = null;
        Animal animal = null;
        try {
            animal_list = new ArrayList<Animal>();
            animal = new Cat();
            animal.setId(5);
            animal.setName("cat");
            animal_list.add(animal);
            animal = new Cat();
            animal.setId(1);
            animal.setName("small cat");
            animal_list.add(animal);
            animal = new Elephant();
            animal.setId(8);
            animal.setName("Big Elephant");
            animal_list.add(animal);
            animal = new Elephant();
            animal.setId(3);
            animal.setName("Elephant");
            animal_list.add(animal);
            Collections.sort(animal_list);
            for (Animal current_animal : animal_list) {
                System.out.println("Animal id: " + current_animal.getId() + " is " + current_animal.getName());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            animal = null;
            animal_list = null;
        }
    }
}

Output:

Terminal
Animal id: 1 is small cat
Animal id: 3 is Elephant
Animal id: 5 is cat
Animal id: 8 is Big Elephant

Hence, in this tutorial, we learnt about the Comparator interface in detail with examples.

Happy Learning 🙂