Sort an ArrayList of Objects with Comparable and Comparator
In this tutorial, we'll see how to sort an ArrayList that contains objects using the two interfaces java.lang.Comparable and java.util.Comparator. If your program requires sorting an ArrayList of String or Integer, it's best to check out these two articles:- Sort a String or Integer ArrayList
- Sort an ArrayList in descending order
The Comparable interface is used when you want to sort a list of objects by comparing two objects with the predefined method object1.compareTo(object2).
Sort an ArrayList using Comparable
First, let's see the sorting result of an arraylist of objects without implementing the Comparable interface.
Let's create a Employe.java class:
public class Employee {
private String name;
private int age;
private long salary;
public String getName() {
return name;
}
public int getAge() {
return age;
}
public long getSalary() {
return salary;
}
public Employee(String name, int age, int salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
@Override
//this method displays employee information
public String toString() {
return "[name=" + this.name + ", age=" + this.age + ", salary=" +
this.salary + "]";
}
}
We want to create a list of ArrayList< Employee>:
Now you must have understood the importance of these two interfaces.
Let's say we want to sort the list by the property: employee's salary. This can be done by implementing the Comparable interface, and then java does an automatic comparison with the compareTo()declared Override.
import java.util.ArrayList;Calling the Collections.sort() cause a problem because it is done on an ArrayList of objects that does not work unless you use both the Comparable and Comparator interfaces. A compilation error appears:
import java.util.Collections;
public class ArrayListComparable {
public static void main(String[] args) {
ArrayList< Employee> arraylist = new ArrayList< Employee> ();
arraylist.add(new Employe("mateo", 32, 20000));
arraylist.add(new Employe("katia", 26, 10000));
arraylist.add(new Employe("aline", 30, 40000));
arraylist.add(new Employe("salim", 28, 35000));
System.out.println("Ordered list of employees:\n"+Collections.sort(arraylist));
}
}
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
The operator + is undefined for the argument type(s) String, void
Bound mismatch: The generic method sort(List) of type Collections is not applicable for the arguments (ArrayList ). The inferred type Employe is not a valid substitute for the bounded parameter >
at ArrayListComparable.main(ArrayListComparable.java:14)
Now you must have understood the importance of these two interfaces.
Let's say we want to sort the list by the property: employee's salary. This can be done by implementing the Comparable interface, and then java does an automatic comparison with the compareTo()declared Override.
After implementing the Comparable interface in the Employe.java class, the result is as follows:
public class Employe implements Comparable< Employee> {Now we have the right to call the method Collections.sort():
private String name;
private int age;
private long salary;
public String getName() {
return name;
}
public int getAge() {
return age;
}
public long getSalary() {
return salary;
}
public Employee(String name, int age, int salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
@Override
//this method displays employee information
public String toString() {
return "[name=" + this.name + ", age=" + this.age + ", salary=" +
this.salary + "]";
}
@Override
public int compareTo(Employee emp) {
//sort employees by age in order croiddant
//retroune a negative, zero, or positive integer if the age
//of that employee is less than, equal to, or greater than the object compared with
return (this.age - emp.age);
}
}
import java.util.ArrayList;When we run this piece of code we will have the following result:
import java.util.Collections;
public class ArrayListComparable {
public static void main(String[] args) {
ArrayList< Employee> arraylist = new ArrayList< Employee> ();
arraylist.add(new Employe("mateo", 32, 20000));
arraylist.add(new Employe("katia", 26, 10000));
arraylist.add(new Employe("aline", 30, 40000));
arraylist.add(new Employe("salim", 28, 35000));
Collections.sort(arraylist);
System.out.println("ordered list of employees by age:\n");
for(Employee e:arraylist)
System.out.println(e);
}
}
ordered list of employees by age:
[name=katia, age=26, salary=10000]
[name=salim, age=28, salary=35000]
[name=aline, age=30, salary=40000]
[name=mateo, age=32, salary=20000]
Sort an ArrayList using Comparator
As you can see, the list of employees above is sorted in ascending order. but why use the Comparator interface then? Because there may be situations where the sorting is based on several parameters unlike Comparable. For example, we want the sorting of employees to be based on name, age, and salary.The compare(Object o1, Object o2) of the Comparator interface takes two objects. In our example, it must be implemented three times (name, age, and salary) so that it returns a negative integer if the first argument is smaller than the second and zero if they are equal and a positive integer if the first argument is larger than the second.
import java.util.Comparator;The test class main:
public class Employee {
private String name;
private int age;
private long salary;
public String getNom() {
return name;
}
public int getAge() {
return age;
}
public long getSalary() {
return salary;
}
public Employee(String name, int age, int salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
@Override
//this method displays employee information
public String toString() {
return "[name=" + this.name + ", age=" + this.age + ", salary=" +
this.salary + "]";
}
/*
* Comparator for sorting employees by name
*/
public static Comparator< Employee> ComparatorName = new Comparator< Employee> () {
@Override
public int compare(Employee e1, Employee e2) {
return e1.getName().compareTo(e2.getName());
}
};
/*
* Comparator for sorting employees by age
*/
public static Comparator< Employee> ComparatorAge = new Comparator< Employee> () {
@Override
public int compare(Employee e1, Employee e2) {
return (int) (e1.getAge() - e2.getAge());
}
};
/*
* Comparator for sorting employees by salary
*/
public static Comparator< Employee> ComparatorSalary = new Comparator< Employee> () {
@Override
public int compare(Employee e1, Employee e2) {
return (int) (e1.getSalary() - e2.getSalary());
}
};
}
import java.util.ArrayList;The execution of this code gives:
import java.util.Collections;
public class main{
public static void main(String[] args) {
ArrayList< Employee> arraylist = new ArrayList< Employee> ();
arraylist.add(new Employe("mateo", 32, 20000));
arraylist.add(new Employe("katia", 26, 10000));
arraylist.add(new Employe("aline", 30, 40000));
arraylist.add(new Employe("salim", 28, 35000));
//sort by name
Collections.sort(arraylist, Employee.ComparatorName);
System.out.println("ordered list of employees by name:");
for(Employee e:arraylist)
System.out.println(e);
//sort by age
Collections.sort(arraylist, Employee.ComparatorAge);
System.out.println("ordered list of employees by age:");
for(Employee e:arraylist)
System.out.println(e);
//sort by salary
Collections.sort(arraylist, Employee.ComparatorSalary);
System.out.println("ordered list of employees by salary:");
for(Employee e:arraylist)
System.out.println(e);
}
}
ordered list of employees by name:
[name=aline, age=30, salary=40000]
[name=katia, age=26, salary=10000]
[name=mateo, age=32, salary=20000]
[name=Salim, age=28, salary=35000]
ordered list of employees by age:
[name=katia, age=26, salary=10000]
[name=salim, age=28, salary=35000]
[name=aline, age=30, salary=40000]
[name=mateo, age=32, salary=20000]
ordered list of employees by salary:
[name=katia, age=26, salary=10000]
[name=mateo, age=32, salary=20000]
[name=salim, age=28, salary=35000]
[name=aline, age=30, salary=40000]