Java provider Comparable and Comparator interface for sorting array/collection of objects. By using these interface we can sort primitive and wrapper classes of array or list.
Here we will see the example of default sort order for primitive types by using java.util.Arrays.sort(). This will sort the primitive by natural order.
import java.util.Arrays;
public class ComparePrimitive {
public static void main(String[] args) {
int[] intArray = {6, 4, 3, 1, 2, 5};
String[] strArray = {"Java", "Css", "Angular", "Python", "Xml"};
Arrays.sort(intArray);
Arrays.sort(strArray);
System.out.println("Sorted Array of int: " + Arrays.toString(intArray));
System.out.println("Sorted Array of String: " + Arrays.toString(strArray));
}
}
Output:
Sorted Array of int: [1, 2, 3, 4, 5, 6]
Sorted Array of String: [Angular, Css, Java, Python, Xml].
Let try the Arrays.sort of Object sorting. For example I will create a Employee class with basic attributes and will try to sort the object by using Arrays.sort method??
Here my Employee class,
public class Employee {
private int id;
private String name;
private double experience;
private long salary;
private int rating;
public Employee(int id, String name, double experience, long salary, int rating) {
this.id = id;
this.name = name;
this.experience = experience;
this.salary = salary;
this.rating = rating;
}
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;
}
public double getExperience() {
return experience;
}
public void setExperience(double experience) {
this.experience = experience;
}
public double getSalary() {
return salary;
}
public void setSalary(long salary) {
this.salary = salary;
}
public int getRating() {
return rating;
}
public void setRating(int rating) {
this.rating = rating;
}
}Here test class to sort the employee object using Arrays.sort().
public class EmployeeSort {
public static void main(String[] args) {
Employee[] employees = {
new Employee(5, "Antwaun", 5.5, 10000L, 1),
new Employee(2, "Rick", 32.5, 450000L, 3),
new Employee(1, "Richard", 50, 600000L, 4),
new Employee(3, "Corey", 12.5, 20000L, 2),
new Employee(4, "Chumlee", 10.5, 15000L, 5)
};
Arrays.sort(employees);
System.out.println("Sorting order of Employee by Id: "+Arrays.toString(employees));
}
}Lets run this main method, OOPS we are getting error, Runtime exception!!!
Exception in thread "main" java.lang.ClassCastException: com.example.monitoring.compare.Employee cannot be cast to java.lang.Comparable
at java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:320)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:188)
at java.util.Arrays.sort(Arrays.java:1246)
at com.example.monitoring.compare.EmployeeSort.main(EmployeeSort.java:14)
Process finished with exit code 1Compiler says cannot case Employee to Comparable. So we need a Comparable type to sorting object.
Oh then how to cast our Employee class to Comparable java??. Yes here we go..
Java provide two interfaces to solve this issue.
- Comparable
- Comparator
public class Employee implements Comparable<Employee>{
private int id;
private String name;
private double experience;
private long salary;
private int rating;
public Employee(int id, String name, double experience, long salary, int rating) {
this.id = id;
this.name = name;
this.experience = experience;
this.salary = salary;
this.rating = rating;
}
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;
}
public double getExperience() {
return experience;
}
public void setExperience(double experience) {
this.experience = experience;
}
public double getSalary() {
return salary;
}
public void setSalary(long salary) {
this.salary = salary;
}
public int getRating() {
return rating;
}
public void setRating(int rating) {
this.rating = rating;
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", name='" + name + '\'' +
", experience=" + experience +
", salary=" + salary +
", rating=" + rating +
'}';
}
@Override
public int compareTo(Employee o) {
return (this.id-o.id);
}
}
Lets run the EmployeeSort,
Output:
Sorting order of Employee by Id: [Employee{id=1, name='Richard', experience=50.0, salary=600000, rating=4}, Employee{id=2, name='Rick', experience=32.5, salary=450000, rating=3}, Employee{id=7, name='Antwaun', experience=5.5, salary=10000, rating=1}, Employee{id=7, name='Corey', experience=12.5, salary=20000, rating=2}, Employee{id=7, name='Chumlee', experience=10.5, salary=15000, rating=5}]
public static Comparator<Employee> nameComparator = new Comparator<Employee>() {
@Override
public int compare(Employee o1, Employee o2) {
return(o1.getName().compareTo(o2.getName()));
}
};
public static Comparator<Employee> salaryComparator = new Comparator<Employee>() {
@Override
public int compare(Employee o1, Employee o2) {
return (int) (o1.getSalary() - o2.getSalary());
}
};
public static Comparator<Employee> ratingComparator = new Comparator<Employee>() {
@Override
public int compare(Employee o1, Employee o2) {
return o1.getRating() - o2.getRating();
}
};
public static Comparator<? super Employee> experienceComparator = new Comparator<Employee>() {
@Override
public int compare(Employee o1, Employee o2) {
return (int) (o1.getExperience() - o2.getExperience());
}
};
We need use these comparator in EmployeeSort class, Changes in EmployeeSort class.
Arrays.sort(employees, Employee.nameComparator);
System.out.println("Sorting order of Employee by Name: "+Arrays.toString(employees));
Arrays.sort(employees, Employee.salaryComparator);
System.out.println("Sorting order of Employee by Salary: "+Arrays.toString(employees));
Arrays.sort(employees, Employee.ratingComparator);
System.out.println("Sorting order of Employee by Rating: "+Arrays.toString(employees));
Arrays.sort(employees, Employee.experienceComparator);
System.out.println("Sorting order of Employee by Experience: "+Arrays.toString(employees));
Output:
Sorting order of Employee by Id: [Employee{id=1, name='Richard', experience=50.0, salary=600000, rating=4}, Employee{id=2, name='Rick', experience=32.5, salary=450000, rating=3}, Employee{id=3, name='Corey', experience=12.5, salary=20000, rating=2}, Employee{id=4, name='Chumlee', experience=10.5, salary=15000, rating=5}, Employee{id=5, name='Antwaun', experience=5.5, salary=10000, rating=1}]
Sorting order of Employee by Name: [Employee{id=5, name='Antwaun', experience=5.5, salary=10000, rating=1}, Employee{id=4, name='Chumlee', experience=10.5, salary=15000, rating=5}, Employee{id=3, name='Corey', experience=12.5, salary=20000, rating=2}, Employee{id=1, name='Richard', experience=50.0, salary=600000, rating=4}, Employee{id=2, name='Rick', experience=32.5, salary=450000, rating=3}]
Sorting order of Employee by Salary: [Employee{id=5, name='Antwaun', experience=5.5, salary=10000, rating=1}, Employee{id=4, name='Chumlee', experience=10.5, salary=15000, rating=5}, Employee{id=3, name='Corey', experience=12.5, salary=20000, rating=2}, Employee{id=2, name='Rick', experience=32.5, salary=450000, rating=3}, Employee{id=1, name='Richard', experience=50.0, salary=600000, rating=4}]
Sorting order of Employee by Rating: [Employee{id=5, name='Antwaun', experience=5.5, salary=10000, rating=1}, Employee{id=3, name='Corey', experience=12.5, salary=20000, rating=2}, Employee{id=2, name='Rick', experience=32.5, salary=450000, rating=3}, Employee{id=1, name='Richard', experience=50.0, salary=600000, rating=4}, Employee{id=4, name='Chumlee', experience=10.5, salary=15000, rating=5}]
Sorting order of Employee by Experience: [Employee{id=5, name='Antwaun', experience=5.5, salary=10000, rating=1}, Employee{id=4, name='Chumlee', experience=10.5, salary=15000, rating=5}, Employee{id=3, name='Corey', experience=12.5, salary=20000, rating=2}, Employee{id=2, name='Rick', experience=32.5, salary=450000, rating=3}, Employee{id=1, name='Richard', experience=50.0, salary=600000, rating=4}]
Here we all used Array of object lets try the same with list.Here I added code in EmployeeSort class. And above output we can see all the order are ascending. For name displaying ascending order is good, but rating, experience and salary we need descending order.Comparator provider reversed() to reverse the sorting order by using that we can list them reverse. I have used it for rating, experience and salary sorting.Here added list of employee object in list. employee1-5 added in above snippet,List<Employee> employeeList = new ArrayList<>();
employeeList.add(employee1);
employeeList.add(employee2);
employeeList.add(employee3);
employeeList.add(employee4);
employeeList.add(employee5);Let we check output one by one
employeeList.sort(Employee.nameComparator);
System.out.println("Sorting order List of Employee by Name: "+employeeList);Output:
Sorting order List of Employee by Name: [Employee{id=5, name='Antwaun', experience=5.5, salary=10000, rating=1}, Employee{id=4, name='Chumlee', experience=10.5, salary=15000, rating=5}, Employee{id=3, name='Corey', experience=12.5, salary=20000, rating=2}, Employee{id=1, name='Richard', experience=50.0, salary=600000, rating=4}, Employee{id=2, name='Rick', experience=32.5, salary=450000, rating=3}]
Let order by salary, here I used reversed() method to get reverse order of salary.
employeeList.sort(Employee.salaryComparator.reversed());
System.out.println("Sorting order List of Employee by Salary: "+employeeList);Output:
Sorting order List of Employee by Salary: [Employee{id=1, name='Richard', experience=50.0, salary=600000, rating=4}, Employee{id=2, name='Rick', experience=32.5, salary=450000, rating=3}, Employee{id=3, name='Corey', experience=12.5, salary=20000, rating=2}, Employee{id=4, name='Chumlee', experience=10.5, salary=15000, rating=5}, Employee{id=5, name='Antwaun', experience=5.5, salary=10000, rating=1}]
Rating order,employeeList.sort(Employee.ratingComparator.reversed());
System.out.println("Sorting order List of Employee by Rating: "+employeeList);Output:
Sorting order List of Employee by Rating: [Employee{id=4, name='Chumlee', experience=10.5, salary=15000, rating=5}, Employee{id=1, name='Richard', experience=50.0, salary=600000, rating=4}, Employee{id=2, name='Rick', experience=32.5, salary=450000, rating=3}, Employee{id=3, name='Corey', experience=12.5, salary=20000, rating=2}, Employee{id=5, name='Antwaun', experience=5.5, salary=10000, rating=1}]
Experience order,employeeList.sort(Employee.experienceComparator.reversed());
System.out.println("Sorting order List of Employee by Experience: "+ employeeList);Output:Sorting order List of Employee by Experience: [Employee{id=1, name='Richard', experience=50.0, salary=600000, rating=4}, Employee{id=2, name='Rick', experience=32.5, salary=450000, rating=3}, Employee{id=3, name='Corey', experience=12.5, salary=20000, rating=2}, Employee{id=4, name='Chumlee', experience=10.5, salary=15000, rating=5}, Employee{id=5, name='Antwaun', experience=5.5, salary=10000, rating=1}]Let see how to work with combination of multiple attribute comparison.public static Comparator<Employee> experienceAndSalaryComparator = new Comparator<Employee>() {
@Override
public int compare(Employee o1, Employee o2) {
int flag = (int) (o1.getExperience() -o2.getExperience());
if(flag == 0){
flag = (int) (o1.getSalary() - o2.getSalary());
}
return flag;
}
};To check this scenario I made some changers in employee input,Employee employee1 = new Employee(5, "Antwaun", 5.5, 10000L, 1);
Employee employee2 = new Employee(2, "Rick", 32.5, 2000L, 3);
Employee employee3 = new Employee(1, "Richard", 50, 3000L, 4);
Employee employee4 = new Employee(3, "Corey", 32.5, 20000L, 2);
Employee employee5 = new Employee(4, "Chumlee", 10.5, 15000L, 5);Lets call new comparator in EmployeeSort class,
employeeList.sort(Employee.experienceAndSalaryComparator.reversed());
System.out.println(employeeList);Output:
[Employee{id=1, name='Richard', experience=50.0, salary=3000, rating=4}, Employee{id=3, name='Corey', experience=32.5, salary=20000, rating=2}, Employee{id=2, name='Rick', experience=32.5, salary=2000, rating=3}, Employee{id=4, name='Chumlee', experience=10.5, salary=15000, rating=5}, Employee{id=5, name='Antwaun', experience=5.5, salary=10000, rating=1}]
Yes almost we covered all the possible implementation on Comparable and comparator interface in java to sort the Object and primitive types.Some common points above sorting,
- Both compare() and compareTo() method returns are below
- first argument is less than second argument return -1
- first argument is equals to second argument return 0
- first argument is greater than second argument return 1.
- compare o1 first argument o2 second argument
- compareTo this first argument o second argument
- Comparable provide single way soring. Comparator provide multiple way of sorting
Thanks all.