Home » Core Java » util » Comparator » Comparator Java Example

About Konstantina Dimtsa

Konstantina has graduated from the Department of Informatics and Telecommunications in National and Kapodistrian University of Athens (NKUA) and she is currently pursuing M.Sc studies in Advanced Information Systems at the same department. She is also working as a research associate for NKUA in the field of telecommunications. Her main interests lie in software engineering, web applications, databases and telecommunications.

Comparator Java Example

In this post, we feature a comprehensive Java comparator Example. We will show how to use java.util.Comparator interface. java.util.Comparator is an interface which is used for sorting objects in Java.

The compare(Object o1, Object o2) method of Comparator interface needs to be implemented for this purpose, which compares two objects and returns an integer, depending on the comparison: positive, if o1 is greater than o2; zero, if o1 equals to o2; negative, if o1 is less than o1.

Another interface which is used for sorting objects is java.lang.Comparable. However, Comparable cannot sort objects on different attributes, while Comparator can. Also, the method compareTo(T o) of Comparable needs to be implemented in this case, which compares the current object (this object) with the specified object for order. In this example, we will pay attention to Comparator interface.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!

1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design

and many more ....

 

1. Example of using Comparator Java interface

We need to use Comparator interface when we want to order objects on different attributes, for example, let’s suppose that an employer would like to order his employees by salary or by name. This cannot be done using Comparable interface.

So, let’s see an example. First of all, let’s create a class that will represent the object that will be sorted. Create a java class named Student.java with the following code:

Student.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package com.javacodegeeks.java.util.comparator;
 
public class Student {
    private String name;
    private int age;
    private String lesson;
    private int grade;
 
    public Student() {
    }
 
    public Student(String name, int age, String lesson, int grade) {
        super();
        this.name = name;
        this.age = age;
        this.lesson = lesson;
        this.grade = grade;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
 
    public String getLesson() {
        return lesson;
    }
 
    public void setLesson(String lesson) {
        this.lesson = lesson;
    }
 
    public int getGrade() {
        return grade;
    }
 
    public void setGrade(int grade) {
        this.grade = grade;
    }
 
    @Override
    public String toString() {
        return "[name=" + this.name + ", age=" + this.age + ", lesson="
                + this.lesson + ", grade=" + this.grade + "]";
    }
 
}

Now, let’s create two classes that will implement the Comparator interface and they will be used so as to sort students with different attributes.
Firstly, create a java class named GradeComparator.java with the following code:

GradeComparator.java

import java.util.Comparator;
import java.util.function.Function;
import java.util.function.ToDoubleFunction;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;

public class GradeComparator implements Comparator {

    public int compare(Student o1, Student o2) {

        // descending order (ascending order would be:
        // o1.getGrade()-o2.getGrade())
        return o2.getGrade() - o1.getGrade();
    }

    @Override
    public int compare(Object o1, Object o2) {
        return 0;
    }

    @Override
    public Comparator reversed() {
        return null;
    }

    @Override
    public Comparator thenComparing(Comparator other) {
        return null;
    }

    @Override
    public Comparator thenComparingInt(ToIntFunction keyExtractor) {
        return null;
    }

    @Override
    public Comparator thenComparingLong(ToLongFunction keyExtractor) {
        return null;
    }

    @Override
    public Comparator thenComparingDouble(ToDoubleFunction keyExtractor) {
        return null;
    }

    @Override
    public Comparator thenComparing(Function keyExtractor) {
        return null;
    }

    @Override
    public Comparator thenComparing(Function keyExtractor, Comparator keyComparator) {
        return null;
    }
}

The above class will sort students by grade, in descending order.
Then, create a java class named NameComparator.java with the following code:

NameComparator.java

import java.util.Comparator;
import java.util.function.Function;
import java.util.function.ToDoubleFunction;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;

public class NameComparator implements Comparator {

    public int compare(Student o1, Student o2) {
        String name1 = o1.getName();
        String name2 = o2.getName();

        // ascending order (descending order would be: name2.compareTo(name1))
        return name1.compareTo(name2);
    }

    @Override
    public int compare(Object o1, Object o2) {
        return 0;
    }

    @Override
    public Comparator reversed() {
        return null;
    }

    @Override
    public Comparator thenComparing(Comparator other) {
        return null;
    }

    @Override
    public Comparator thenComparingInt(ToIntFunction keyExtractor) {
        return null;
    }

    @Override
    public Comparator thenComparingLong(ToLongFunction keyExtractor) {
        return null;
    }

    @Override
    public Comparator thenComparingDouble(ToDoubleFunction keyExtractor) {
        return null;
    }

    @Override
    public Comparator thenComparing(Function keyExtractor) {
        return null;
    }

    @Override
    public Comparator thenComparing(Function keyExtractor, Comparator keyComparator) {
        return null;
    }
}

This class will sort students by Name, in ascending order.

As we mentioned above, classes that implement the Comparator interface need to override the compare() method. In this specific example, the sorting of grades will be in descending order as we have reversed the objects o1, o2. For the comparison of names, we used the int compareTo(String anotherString) method.

Finally, create a java class named MainComparatorExample.java, which will be the main class of our example:

MainComparatorExample.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package com.javacodegeeks.java.util.comparator;
 
import java.util.Arrays;
 
public class MainComparatorExample {
 
    public static void main(String args[]) {
        Student student[] = new Student[3];
 
        student[0] = new Student();
        student[0].setName("Nick");
        student[0].setGrade(19);
 
        student[1] = new Student();
        student[1].setName("Helen");
        student[1].setGrade(12);
 
        student[2] = new Student();
        student[2].setName("Ross");
        student[2].setGrade(16);
 
        System.out.println("Order of students before sorting is: ");
 
        for (int i = 0; i < student.length; i++) {
            System.out.println(student[i].getName() + "\t"
                    + student[i].getGrade());
        }
 
        Arrays.sort(student, new GradeComparator());
        System.out
                .println("Order of students after sorting by student grade is");
 
        for (int i = 0; i < student.length; i++) {
            System.out.println(student[i].getName() + "\t"
                    + student[i].getGrade());
        }
 
        Arrays.sort(student, new NameComparator());
        System.out
                .println("Order of students after sorting by student name is");
 
        for (int i = 0; i < student.length; i++) {
            System.out.println(student[i].getName() + "\t"
                    + student[i].getGrade());
        }
    }
 
}

Let’s explain the above code. We create an array of Students, three objects of type Student and then, we set the name and the final grade for each one of them. After that, we print to the output the array without sorting, then we sort the array (a) by grade and (b) by name, and finally, we print to the output the respective results. The sorting can be done by using the method sort(T[] a, Comparator c) of java.util.Arrays, which sorts the array of Students according to the order induced by the specified comparator (either NameComparator or GradeComparator, respectively).

If we run the above code, we will have the following results:

Output

01
02
03
04
05
06
07
08
09
10
11
12
Order of students before sorting is:
Nick    19
Helen   12
Ross    16
Order of students after sorting by student grade is
Nick    19
Ross    16
Helen   12
Order of students after sorting by student name is
Helen   12
Nick    19
Ross    16

2. Sort Objects on More than one Fields

In this section, we will discuss how to sort objects based on more than one attribute of the object itself. For this, we will use the Comparator interface, which actually allows us to compare objects using compare() methods with more than one attribute.

We will consider the example of the employee class which contains some basic details about the employees. This class implements Comparable interface to implement the compareTo() function to show the natural order but also exposes a SalaryComparator property which is an anonymous class to sort the employees based on Salary of the employees.

The code is shown below.Employee.java

import java.util.Comparator;

public class Employee implements Comparable<Employee> {

    private int id;
    private String name;
    private int age;
    private long salary;

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public long getSalary() {
        return salary;
    }

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

    @Override
    public int compareTo(Employee emp) {
        return (this.id - emp.id);
    }

    @Override
    public String toString() {
        return "[id=" + this.id + ", name=" + this.name + ", age=" + this.age + ", salary=" +
                this.salary + "]" + "\n";
    }

    public static Comparator<Employee> SalaryComparator = new Comparator<Employee>() {

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

}

After this, we have created a class called EmployeeComparatorByIdAndName, which sorts employees based on Id and name of the employees.EmployeeComparatorByIdAndName.java

import java.util.Comparator;

public class EmployeeComparatorByIdAndName implements Comparator<Employee> {

    @Override
    public int compare(Employee o1, Employee o2) {
        int flag = o1.getId() - o2.getId();
        if (flag == 0) flag = o1.getName().compareTo(o2.getName());
        return flag;
    }
}

We have created a driver class called ComparatorMultipleAttributeExample,ComparatorMultipleAttributeExample.java

import java.util.Arrays;

public class ComparatorMultipleAttributeExample {


    public static void main(String[] args) {

        Employee[] employeeList = new Employee[4];
        employeeList[0] = new Employee(10, "Neo", 25, 100000);
        employeeList[1] = new Employee(20, "Dhruv", 29, 200000);
        employeeList[2] = new Employee(5, "Akshay", 35, 500000);
        employeeList[3] = new Employee(1, "Abhay", 32, 5000);

        //sorting employees array using Comparable interface implementation
        Arrays.sort(employeeList);
        System.out.println("Default Sorting of Employees list:\n" + Arrays.toString(employeeList));

        //sort employees array using Comparator by Salary
        Arrays.sort(employeeList, Employee.SalaryComparator);
        System.out.println("Employees list sorted by Salary:\n" + Arrays.toString(employeeList));

        //Employees list sorted by ID and then name using Comparator class
        employeeList[0] = new Employee(1, "Gagan", 25, 10000);
        Arrays.sort(employeeList, new EmployeeComparatorByIdAndName());
        System.out.println("Employees list sorted by ID and Name:\n" + Arrays.toString(employeeList));
    }
}

The output of ComparatorMultipleAttributeExample.java is shown in snapshot below.

Comparator Java - ComparatorMultipleAttributeExample.java
Output of ComparatorMultipleAttributeExample.java

3. The Comparing Method

From our Java 8 Comparator example:

The comparator has a new method i.e. comparing() which uses an instance of the java.util.function.Function functional interface. This method is specified by using the lambda expressions or its equivalent method reference for creating the Comparator instance. The comparing() method has the following signature.

1
static <T,U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T,? extends U> keyE

This method works by taking a Function<T,R> functional interface instance as an input, where T is the type of input object and R is the sort key which is returned (or extracted) from the input object when Function<T,R> processes it. In addition, developers can now implement the multiple sort criteria’s which can be clubbed using the comparing() method with a thenComparing() method. Java8 Comparator provides a default method thenComparing() which has the following signature.

1
default Comparator<T> thenComparing(Comparator<? super T> other)

This method does the second level sorting if in case the first level sorting is indecisive.

4. Comparable V/s Comparator

So how do we decide when to use Comparable interface and when to use Comparator interface. It depends on the use-case basically.

Just to give a comparative analysis,Comparable provides sorting based on one attribute of the object only with natural ordering and Comparator interface lets you sort objects based on more that one attribute.

Comparable interface implements the sorting logic using compareTo() method in the current class, i.e., the sorting logic is coupled with the class implementing the Comparable interface. On the other hand, Comparator interface implements the sorting logic using compare() method, in a separate class, which increases decoupling.

Comparable is present in java.lang package and Comparator is present in the java.util package.

5. Download the source code

This was an example of Comparator.

Download
Download the Eclipse project from here: Comparator Java Example

Last Updated on Feb. 3rd, 2020

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!

 

1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design

 

and many more ....

 

Receive Java & Developer job alerts in your Area

 

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
Magic
Magic
3 years ago

It would have been better to read about comparing by multiple fields and how you could achieve that using different approaches: implementing by hand, using the CompareToBuilder (apache lang, before jdk8) or using the streaming API (in case of Java8). And of course, the code above should have been nullsafe.