Java Sort Arraylist Collections Sort Comparator 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 the two common ways which are easy to understand and implement. That are, using a chained comparator, and 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:

package net.codejava.collections;  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; 	}  	// getters and setters  	public String toString() { 		return String.format("%s\t%s\t%d\t%d", name, jobTitle, age, salary); 	} }

Note that the Employee class overrides the toString() method in order to provide a meaningful information of an Employee object when printing the object using the System.out.println() method.


2. Using a chained Comparator

Create the EmployeeChainedComparator class looks like as follows:

package net.codejava.collections;  import java.util.Arrays; import java.util.Comparator; import java.util.List;  /**  * This is a chained comparator that is used to sort a list by multiple  * attributes by chaining a sequence of comparators of individual fields  * together.  * @author www.codejava.net  *  */ public class EmployeeChainedComparator implements Comparator<Employee> {  	private List<Comparator<Employee>> listComparators;  	@SafeVarargs 	public EmployeeChainedComparator(Comparator<Employee>... comparators) { 		this.listComparators = Arrays.asList(comparators); 	}  	@Override 	public int compare(Employee emp1, Employee emp2) { 		for (Comparator<Employee> comparator : listComparators) { 			int result = comparator.compare(emp1, emp2); 			if (result != 0) { 				return result; 			} 		} 		return 0; 	} }

The key points here are this comparator takes a list of comparators passed via its constructor; and the compare() method iterates over this comparators list to compare two Employee objects by each individual comparator. Now, we create separate comparators for each field by which we want to sort: job title, age and salary.

Job title comparator:

package net.codejava.collections;  import java.util.Comparator;  /**  * This comparator compares two employees by their job titles.  * @author www.codejava.net  *  */ public class EmployeeJobTitleComparator implements Comparator<Employee> {  	@Override 	public int compare(Employee emp1, Employee emp2) { 		return emp1.getJobTitle().compareTo(emp2.getJobTitle()); 	} }

Age comparator:

package net.codejava.collections;  import java.util.Comparator;  /**  * This comparator compares two employees by their ages.  * @author www.codejava.net  *  */ public class EmployeeAgeComparator implements Comparator<Employee> {  	@Override 	public int compare(Employee emp1, Employee emp2) { 		return emp1.getAge() - emp2.getAge(); 	} }

Salary comparator:

package net.codejava.collections;  import java.util.Comparator;  /**  * This comparator compares two employees by their salaries.  * @author www.codejava.net  *  */ public class EmployeeSalaryComparator implements Comparator<Employee> {  	@Override 	public int compare(Employee emp1, Employee emp2) { 		return emp1.getSalary() - emp2.getSalary(); 	} }

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

package net.codejava.collections;  import java.util.ArrayList; import java.util.Collections; import java.util.List;  /**  * This program demonstrates how to sort a list collection by multiple  * attributes using a chained comparator.  *  * @author www.codejava.net  *  */ public class SortingMultipleAttributesExample {  	public static void main(String[] args) {  		System.out.println("===== SORTING BY MULTIPLE ATTRIBUTES =====");  		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));  		System.out.println("*** Before sorting:");  		for (Employee emp : listEmployees) { 			System.out.println(emp); 		}  		Collections.sort(listEmployees, new EmployeeChainedComparator( 				new EmployeeJobTitleComparator(), 				new EmployeeAgeComparator(), 				new EmployeeSalaryComparator()) 		);  		System.out.println("\n*** After sorting:");  		for (Employee emp : listEmployees) { 			System.out.println(emp); 		}  	} }

Output:

===== SORTING BY MULTIPLE ATTRIBUTES ===== *** Before sorting: Tom		Developer	45	80000 Sam		Designer	30	75000 Bob		Designer	45	134000 Peter	Programmer	25	60000 Tim		Designer	45	130000 Craig	Programmer	30	52000 Anne	Programmer	25	51000 Alex	Designer	30	120000 Bill	Programmer	22	30000 Samuel	Developer	28	80000 John	Developer	35	67000 Patrick	Developer	35	140000 Alice	Programmer	35	80000 David	Developer	35	99000 Jane	Designer	30	82000  *** After sorting: Sam		Designer	30	75000 Jane	Designer	30	82000 Alex	Designer	30	120000 Tim		Designer	45	130000 Bob		Designer	45	134000 Samuel	Developer	28	80000 John	Developer	35	67000 David	Developer	35	99000 Patrick	Developer	35	140000 Tom		Developer	45	80000 Bill	Programmer	22	30000 Anne	Programmer	25	51000 Peter	Programmer	25	60000 Craig	Programmer	30	52000 Alice	Programmer	35	80000

As we can see, the list of employees is sorted firstly by job title, secondly by age, and finally salary, in ascending order.

3. 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:

package net.codejava.collections;  import java.util.Comparator;  import org.apache.commons.lang3.builder.CompareToBuilder;  /**  * This comparator sorts a list of Employees by job title, age and salary  * into ascending order.  * @author www.codejava.net  *  */ public class EmployeeComparator implements Comparator<Employee> {  	@Override 	public int compare(Employee o1, Employee o2) { 		return new CompareToBuilder() 				.append(o1.getJobTitle(), o2.getJobTitle()) 				.append(o1.getAge(), o2.getAge()) 				.append(o1.getSalary(), o2.getSalary()).toComparison(); 	} }

And sort the list using this comparator:

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

Output is as same as using the chained comparator above.

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

4. Switching sort order: ascending to descending

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 and age in ascending order, but by salary in descending order:

public class EmployeeComparator implements Comparator<Employee> {  	@Override 	public int compare(Employee o1, Employee o2) { 		return new CompareToBuilder() 				.append(o1.getJobTitle(), o2.getJobTitle()) 				.append(o1.getAge(), o2.getAge()) 				.append(o2.getSalary(), o1.getSalary()).toComparison(); 	} }

When running the above test program with this comparator, the output will be:

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

Related Sorting tutorials:

  • Sorting Arrays Examples (with Comparable and Comparator)
  • Sorting List Collections Examples

Other Java Collections Tutorials:

  • Java Set Tutorial
  • Java Map  Tutorial
  • Java List Tutorial and
  • Java Queue Tutorial
  • Understanding equals() and hashCode() in Java
  • Understanding Object Ordering in Java with Comparable and Comparator
  • 18 Java Collections and Generics Best Practices

About the Author:

Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He started programming with Java in the time of Java 1.4 and has been falling in love with Java since then. Make friend with him on Facebook and watch his Java videos you YouTube.

Add comment

smithbeld1989.blogspot.com

Source: https://www.codejava.net/java-core/collections/sorting-a-list-by-multiple-attributes-example

0 Response to "Java Sort Arraylist Collections Sort Comparator Example"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel