Java Comparator Example for Custom Sorting Employee by Name, Age and Salary (original) (raw)
In this tutorial, we will see the Java Comparator example to sort an Employee object by name, age, and salary. In order to sort Employee object on different criteria, we need to create multiple comparators e.g. NameComparator, AgeComparator, and SalaryComparator, this is known as custom sorting in Java. This is different from the natural ordering of objects, provided by the compareTo() method of java.lang.Comparable interface. Though both compare() and compareTo() method looks similar they are different in the sense that, former accepts one parameter, while later accepts two-parameter. Former compare passed object to the current object, on the other hand, compare() method compares two different objects passed to it.
You can create this comparator as a nested static class because they require access to private members of the class.
Once you create these Comparator implementations, all you need to do is to override compare() method accordingly e.g. in compare() method of NameComparator compare the name of two employees and return positive if the name of the first employee is greater than the second, and return negative if the name of the first employee is less than second and return zero if the name of both employees is equal.
By using Generics, you can avoid casting an object into the Employee inside compare() method, as shown in the example of this article. Once you have your Comparator classes ready, you can create a bunch of employees and sort them using any Comparator by passing List of employees and Comparator into Collections.sort(List, Comparator) method.
By the way, this Java example also implements equals(), hashcode(), compareTo(), and toString() method for Employee object, along with JUnit test for testing various Comparator implementation in file EmployeeTest.java.
And, If you are new to the Java world then I also recommend you go through The Complete Java MasterClass on Udemy to learn Java in a better and more structured way. This is one of the best and up-to-date courses to learn Java online.
Custom Sorting in Java using Comparator Example
Here is the complete code of creating different Comparator classes to compare objects on different attributes. In our example, we have an Employee object, which has fields like int id, String name, int salary, int age, and Date field to represent the date of joining. Our requirement is to sort a List of employees based upon their name, age, salary, and date of joining.
For this purpose, we have created four different comparator classes namely NameComparator, AgeComparator, SalaryComparator, and DOJComparator.
All classes implement java.util.Comparator interface but their compare() method are overridden differently e.g. first one compares the name of two employee object, second compare their salary, third compare their age and last one compares their age.
When overriding compare() method, if you find an object, which overrides compareTo() then invoke that, for example for comparing String and Date we are invoking their compareTo() methods.
Files to run this Example
Employee.java
EmployeeTest.java
In order to run this program, simply copy-paste the following two classes into two different Java source files. Then name them according to the name of the public class e.g. Employee.java and EmployeeTest.java. You also need JUnit to run a test file, which tests the code you have written for implementing Comparator and overriding compare() method.
You can run it on Eclipse or command prompt as per your convenience. If you are not using JUnit then you just put the test code inside the main method of any class and run it accordingly.
Employee.java
===============
import java.util.Comparator;
import java.util.Date;
/**
*
* @author
*/
public class Employee implements Comparable{
private int id;
private String name;
private int salary;
private int age;
private Date dateOfJoining;
public static final Comparator AgeComparator = new Comparator(){
@Override
public int compare(Employee o1, Employee o2) {
return o1.age - o2.age; // This will work because age is positive integer
}
};
public static final Comparator SalaryComparator = new Comparator(){
@Override
public int compare(Employee o1, Employee o2) {
return o1.salary - o2.salary; // salary is also positive integer
}
};
public static final Comparator NameComparator = new Comparator(){
@Override
public int compare(Employee o1, Employee o2) {
return o1.name.compareTo(o2.name);
}
};
public static final Comparator DOJComparator = new Comparator(){
@Override
public int compare(Employee o1, Employee o2) {
return o1.dateOfJoining.compareTo(o2.dateOfJoining);
}
};
public Employee(int id, String name, int salary, int age, Date dateOfJoining) {
this.id = id;
this.name = name;
this.salary = salary;
this.age = age;
this.dateOfJoining = dateOfJoining;
}
@Override
public String toString() {
return "Employee{" + "id=" + id + ", name=" + name + ", salary=" + salary + ", age=" + age + ", dateOfJoining=" + dateOfJoining + '}';
}
@Override
public int compareTo(Employee o) {
return this.id - o.id;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Employee other = (Employee) obj;
if (this.id != other.id) {
return false;
}
if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
return false;
}
if (this.salary != other.salary) {
return false;
}
if (this.age != other.age) {
return false;
}
if (this.dateOfJoining != other.dateOfJoining && (this.dateOfJoining == null || !this.dateOfJoining.equals(other.dateOfJoining))) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 5;
hash = 47 * hash + this.id;
hash = 47 * hash + (this.name != null ? this.name.hashCode() : 0);
hash = 47 * hash + this.salary;
hash = 47 * hash + this.age;
hash = 47 * hash + (this.dateOfJoining != null ? this.dateOfJoining.hashCode() : 0);
return hash;
}
}
EmployeeTest.java
==================
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Test class to test sorting of Employee object on different parameters.
* each test method will test each Comparator implementation.
* @author http://javarevisited.blogpot.com
*/
public class EmployeeTest {
@Test
public void testEmployeeSorting(){
Employee e1 = new Employee(1, "A", 1000, 32, new Date(2011, 10, 1));
Employee e2 = new Employee(2, "AB", 1300, 22, new Date(2012, 10, 1));
Employee e3 = new Employee(3, "B", 10, 42, new Date(2010, 11, 3));
Employee e4 = new Employee(4, "CD", 100, 23, new Date(2011, 10, 1));
Employee e5 = new Employee(5, "AAA", 1200, 26, new Date(2011, 10, 1));
List listOfEmployees = new ArrayList();
listOfEmployees.add(e1);
listOfEmployees.add(e2);
listOfEmployees.add(e3);
listOfEmployees.add(e4);
listOfEmployees.add(e5);
System.out.println("Unsorted List : " + listOfEmployees);
Collections.sort(listOfEmployees); //Sorting by natural order
assertEquals(e1, listOfEmployees.get(0));
assertEquals(e5, listOfEmployees.get(4));
Collections.sort(listOfEmployees, Employee.NameComparator);
assertEquals(e1, listOfEmployees.get(0));
assertEquals(e4, listOfEmployees.get(4));
Collections.sort(listOfEmployees, Employee.AgeComparator);
assertEquals(e2, listOfEmployees.get(0));
assertEquals(e3, listOfEmployees.get(4));
Collections.sort(listOfEmployees, Employee.SalaryComparator);
assertEquals(e3, listOfEmployees.get(0));
assertEquals(e2, listOfEmployees.get(4));
Collections.sort(listOfEmployees, Employee.DOJComparator);
assertEquals(e3, listOfEmployees.get(0));
assertEquals(e2, listOfEmployees.get(4));
}
}
That's all on this Java Comparator example tutorial. We have learned how to create multiple Comparators in a class for comparing objects in different parameters. This allows you to sort objects in any custom order, depending upon business requirements.
You can provide a custom Comparator is a nested static class because a Comparator is closely associated with the object it compares.
This is one of the genuine usages of nested static classes in Java. It's good to provide natural ordering of objects via the compareTo() method and provide additional compare() methods for custom sorting of objects in Java.
Always use Generics while overriding compare(), this will make your program as now your compare() will accept two Employee objects, instead of two java.lang.Object parameters.
Other Java Collection tutorials you may like
- How to sort a Map by keys and values in Java? (tutorial)
- How to sort an ArrayList in ascending and descending order in Java? (tutorial)
- What is the difference between ArrayList and HashSet in Java? (answer)
- What is the difference between TreeMap and TreeSet in Java? (answer)
- What is the difference between HashMap and ConcurrentHashMap in Java? (answer)
- The difference between HashSet and TreeSet in Java? (answer)
- The difference between ArrayList and LinkedList in Java? (answer)
- The difference between Vector and ArrayList in Java? (answer)
Thanks for reading this article so far. If you like this article then please share it with your friends and colleagues. If you have any questions or feedback then please drop a comment.