Sunday 13 July 2014

Sorting a list by multiple attributes example

There are several ways in order to sort a list collection by multiple attributes (keys) of its elements type. For example, sorting a list of employees by their job title, then by age, and then by salary.

In this article, we are going to discuss using a CompareToBuilder class of the Apache Commons Lang library.



1. The model class


Suppose that we have to manage a list of employees whose type is declared by the following class:

public class Employee {
    private String name;
    private String jobTitle;
    private int age;
    private int salary;

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

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getJobTitle() {
        return jobTitle;
    }

    public void setJobTitle(String jobTitle) {
        this.jobTitle = jobTitle;
    }

    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public int getSalary() {
        return salary;
    }
    public void setSalary(int salary) {
        this.salary = salary;
    }
    public String toString() {
        return String.format("%s\t%s\t%d\t%d", name, jobTitle, age, salary);
    }
}


2. Using a CompareToBuilder


The Apache Commons Lang API provides the CompareToBuilder class that can be used to sort a list collection by multiple attributes in a much simpler way. Just write a comparator as simple as follows:

To reverse sort order from ascending to descending of a particular attribute, simply swap the order of the two objects being compared in the comparator. For example, the following comparator sorts the list by job title in ascending order, but by  age and salary in descending order


import org.apache.commons.lang.builder.CompareToBuilder;
import java.util.Comparator;


public class EmployeeComparator implements Comparator<Employee> {

    public int compare(Employee o1, Employee o2) {
        return new CompareToBuilder()
                .append(o1.getJobTitle(), o2.getJobTitle())
                .append(o2.getAge(), o1.getAge())
                .append(o2.getSalary(), o1.getSalary()).toComparison();
    }
}

And note that you have to put the commons-lang-VERSION.jar file to the classpath.


Now, write a test program with some dummy data as follows:



public class SortingMultipleAttributesExample {

    public static void main(String[] args) {
    List<Employee> listEmployees = new ArrayList<Employee>();

    listEmployees.add(new Employee("Tom", "Developer", 45, 80000));
    listEmployees.add(new Employee("Sam", "Designer", 30, 75000));
    listEmployees.add(new Employee("Bob", "Designer", 45, 134000));
    listEmployees.add(new Employee("Peter", "Programmer", 25, 60000));
    listEmployees.add(new Employee("Tim", "Designer", 45, 130000));
    listEmployees.add(new Employee("Craig", "Programmer", 30, 52000));
    listEmployees.add(new Employee("Anne", "Programmer", 25, 51000));
    listEmployees.add(new Employee("Alex", "Designer", 30, 120000));
    listEmployees.add(new Employee("Bill", "Programmer", 22, 30000));
    listEmployees.add(new Employee("Samuel", "Developer", 28, 80000));
    listEmployees.add(new Employee("John", "Developer", 35, 67000));
    listEmployees.add(new Employee("Patrick", "Developer", 35, 140000));
    listEmployees.add(new Employee("Alice", "Programmer", 35, 80000));
    listEmployees.add(new Employee("David", "Developer", 35, 99000));
    listEmployees.add(new Employee("Jane", "Designer", 30, 82000));
    listEmployees.add(new Employee("Alex", "Designer", 25, 120000));

        Collections.sort(listEmployees, new EmployeeComparator());

        for (Employee emp : listEmployees) {
            System.out.println(emp);
        }
    }

}


OutPut :-
------------


Bob Designer 45 134000
Tim Designer 45 130000
Alex Designer 30 120000
Jane Designer 30 82000
Sam Designer 30 75000
Alex Designer 25 120000
Tom Developer 45 80000
Patrick Developer 35 140000
David Developer 35 99000
John Developer 35 67000
Samuel Developer 28 80000
Alice Programmer 35 80000
Craig Programmer 30 52000
Peter Programmer 25 60000
Anne Programmer 25 51000
Bill Programmer 22 30000


No comments:

Post a Comment