Using Comparator to sort a list of objects
Using Comparator to sort a list of objects
Using Java's sort function is very easy when you have an array or list of simple data types like integer or double, but what happens when you have a more complex object and you want to be able to sort by different fields?
This is where java.util.Comparator comes in. We will also be using a technique called Anonymous Inner Classes to implement our different Comparators.
We have a simple class, Employee
public static class Employee
{
String id;
String name;
int salary;
public Employee(String id, String name, int salary)
{
this.id = id;
this.name = name;
this.salary = salary;
}
public String getID()
{
return id;
}
public String getName()
{
return name;
}
public int getSalary()
{
return salary;
}
We want to make functions to sort by each of the member variables.
For the first one, id, we make a Comparator like this:
// Make anonymous inner class to sort by member variable 'id'
public static Comparator<Employee> SortByEmployeeID = new Comparator<Employee>()
{
@Override
public int compare(Employee employee1, Employee employee2)
{
return employee1.getID().compareTo(employee2.getID());
}
};
An anonymous class allows you to declare and instantiate the class at the same time. Here we are declaring a Comparator named SortByEmployeeID that is given as parameters two Employee Objects, and returns a String compareTo on the values from the getID() method. This is then used by the Collections.sort() function you will see later.
We can make a comparator for the next string field in exactly the same way.
When we get to the integer field, we do it slightly differently:
// Make anonymous inner class to sort by member variable 'salary' - integer instead of string
public static Comparator<Employee> SortBySalary = new Comparator<Employee>()
{
public int compare(Employee employee1, Employee employee2)
{
return employee1.getSalary() - employee2.getSalary();
}
};
Here we just subtract the second integer value from the first. This will give us an ascending sort. for a descending sort, we just reverse that:
// Make anonymous inner class to sort by member variable 'salary' - Descending
public static Comparator<Employee> SortBySalaryDescending = new Comparator<Employee>()
{
public int compare(Employee employee1, Employee employee2)
{
// simply reverse for descending
return employee2.getSalary() - employee1.getSalary();
}
};
To use these the syntax is simple:
// sort by id
Collections.sort(employeeList, Employee.SortByEmployeeID);
So, lets put it all together:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.lang.Object;
public class ObjectComparator
{
// create simple class
public static class Employee
{
String id;
String name;
int salary;
public Employee(String id, String name, int salary)
{
this.id = id;
this.name = name;
this.salary = salary;
}
public String getID()
{
return id;
}
public String getName()
{
return name;
}
public int getSalary()
{
return salary;
}
// Make anonymous inner class to sort by member variable 'id'
public static Comparator<Employee> SortByEmployeeID = new Comparator<Employee>()
{
@Override
public int compare(Employee employee1, Employee employee2)
{
return employee1.getID().compareTo(employee2.getID());
}
};
// Make anonymous inner class to sort by member variable 'Name'
public static Comparator<Employee> SortByEmployeeName = new Comparator<Employee>()
{
public int compare(Employee employee1, Employee employee2)
{
return employee1.getName().compareTo(employee2.getName());
}
};
// Make anonymous inner class to sort by member variable 'salary' - integer instead of string
public static Comparator<Employee> SortBySalary = new Comparator<Employee>()
{
public int compare(Employee employee1, Employee employee2)
{
return employee1.getSalary() - employee2.getSalary();
}
};
// Make anonymous inner class to sort by member variable 'salary' - Descending
public static Comparator<Employee> SortBySalaryDescending = new Comparator<Employee>()
{
public int compare(Employee employee1, Employee employee2)
{
// simply reverse for descending
return employee2.getSalary() - employee1.getSalary();
}
};
public String toString()
{
return "Employee ID:" + id + "\n" + "Name:" + name + "\n"
+ "Salary: " + salary + "\n";
}
}
public static void main (String args[])
{
// Make list and add some Employees
ArrayList<Employee> employeeList = new ArrayList<>();
employeeList.add(new Employee("7123r","Dole, Bob", 42000));
employeeList.add(new Employee("1234d","Johnson, John", 150000));
employeeList.add(new Employee("2345x","Billson, Bill", 35000));
employeeList.add(new Employee("0019b","Dickerson, Dick", 10000));
// Display unsorted list
System.out.println("Unsorted ==========================");
for (Employee current : employeeList)
{
System.out.println(current);
}
// sort by id
Collections.sort(employeeList, Employee.SortByEmployeeID);
System.out.println("Sorted by ID =========================");
for (Employee current : employeeList)
{
System.out.println(current);
}
// sort by name
Collections.sort(employeeList, Employee.SortByEmployeeName);
System.out.println("Sorted by NAME =========================");
for (Employee current : employeeList)
{
System.out.println(current);
}
// sort by salary
Collections.sort(employeeList, Employee.SortBySalary);
System.out.println("Sorted by SALARY =========================");
for (Employee current : employeeList)
{
System.out.println(current);
}
// sort by salary - descending
Collections.sort(employeeList, Employee.SortBySalaryDescending);
System.out.println("Sorted by SALARY DESCENDING=========================");
for (Employee current : employeeList)
{
System.out.println(current);
}
}
}
And here is the output:
Unsorted ==========================
Employee ID:7123r
Name:Dole, Bob
Salary: 42000
Employee ID:1234d
Name:Johnson, John
Salary: 150000
Employee ID:2345x
Name:Billson, Bill
Salary: 35000
Employee ID:0019b
Name:Dickerson, Dick
Salary: 10000
Sorted by ID =========================
Employee ID:0019b
Name:Dickerson, Dick
Salary: 10000
Employee ID:1234d
Name:Johnson, John
Salary: 150000
Employee ID:2345x
Name:Billson, Bill
Salary: 35000
Employee ID:7123r
Name:Dole, Bob
Salary: 42000
Sorted by NAME =========================
Employee ID:2345x
Name:Billson, Bill
Salary: 35000
Employee ID:0019b
Name:Dickerson, Dick
Salary: 10000
Employee ID:7123r
Name:Dole, Bob
Salary: 42000
Employee ID:1234d
Name:Johnson, John
Salary: 150000
Sorted by SALARY =========================
Employee ID:0019b
Name:Dickerson, Dick
Salary: 10000
Employee ID:2345x
Name:Billson, Bill
Salary: 35000
Employee ID:7123r
Name:Dole, Bob
Salary: 42000
Employee ID:1234d
Name:Johnson, John
Salary: 150000
Sorted by SALARY DESCENDING=========================
Employee ID:1234d
Name:Johnson, John
Salary: 150000
Employee ID:7123r
Name:Dole, Bob
Salary: 42000
Employee ID:2345x
Name:Billson, Bill
Salary: 35000
Employee ID:0019b
Name:Dickerson, Dick
Salary: 10000
Posted Apr 18, 2015, 10:02 PM UTC