In Java, it’s pretty easy to sort elements in a list collection using the Collections.sort() static utility method. This method has two forms as follows:

    • void sort(List<T> list): sorts the list into ascending order according to its elements’ natural ordering.
    • void sort(List<T> list, Comparator<? super T> c): sorts the list into the order specified by the given comparator.
Behind the scenes, the sort operation uses a merge sort algorithm which is slightly optimized to be fast and stable:

    • Fast: it guarantees O(n log n) performance in average and worst cases, and runs faster if the original list is nearly sorted.
    • Stable: it preservers the order the equal elements so it’s useful for sorting the list repeatedly on different attributes.
Let’s dive into some detailed examples.

Table of content:

    1. Sorting a list according to natural ordering of elements
    2. Reversing sort order
    3. Sorting a list whose elements of a custom type
    4. Sorting a list using a Comparator

1. Sorting a list according to natural ordering of elements

Basically, a list can be sorted if only all of its elements are mutually comparable by implementing the Comparableinterface. If a class implements the Comparableinterface, it is considered as having natural ordering which allows objects of that class to be sorted by the Collections.sort(list) method.

All basic data type wrapper classes in Java have natural ordering: String, Character, Byte, Date, Integer, Float, etc. Here are some examples:

    • Sorting a list of Strings:

      List<String> listStrings = Arrays.asList("Orange", "Grape", "Apple", "Lemon", "Banana");
      
      System.out.println("Before sorting: " + listStrings);
      
      Collections.sort(listStrings);
      
      System.out.println("After sorting: " + listStrings);

      Output:
      Before sorting: [Orange, Grape, Apple, Lemon, Banana]
      After sorting: [Apple, Banana, Grape, Lemon, Orange]
       

    • Sorting a list of Characters:

      List<Character> listCharacters = Arrays.asList('F', 'C', 'A', 'B', 'Z', 'E', 'K', 'P');
      
      System.out.println("Before sorting: " + listCharacters);
      
      Collections.sort(listCharacters);
      
      System.out.println("After sorting: " + listCharacters);

      Output:
      Before sorting: [F, C, A, B, Z, E, K, P]
      After sorting: [A, B, C, E, F, K, P, Z]
       

    • Sorting a list of Integers:
      List<Integer> listIntegers = Arrays.asList(1, 6, 9, 3, 2, 0, 8, 4, 7, 5);
      
      System.out.println("Before sorting: " + listIntegers);
      
      Collections.sort(listIntegers);
      
      System.out.println("After sorting: " + listIntegers);

      Output:
      Before sorting: [1, 6, 9, 3, 2, 0, 8, 4, 7, 5]
      After sorting: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
       

    • Sorting a list of Dates:

      List<Date> listDates = new ArrayList<Date>();
      DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
      
      try {
      	listDates.add(dateFormatter.parse("2013-09-30"));
      	listDates.add(dateFormatter.parse("2013-07-06"));
      	listDates.add(dateFormatter.parse("2013-11-28"));
      } catch (ParseException ex) {
      	System.err.print(ex);
      }
      
      System.out.println("Before sorting: " + listDates);
      
      Collections.sort(listDates);
      
      System.out.println("After sorting: " + listDates);

      Output:
      Before sorting: [Mon Sep 30 00:00:00 ICT 2013, Sat Jul 06 00:00:00 ICT 2013, Thu Nov 28 00:00:00 ICT 2013]
      After sorting: [Sat Jul 06 00:00:00 ICT 2013, Mon Sep 30 00:00:00 ICT 2013, Thu Nov 28 00:00:00 ICT 2013]


       

2. Reversing sort order

Because the sort(list) method always sorts the specified list into ascending order, so if we want to sort by descending order, we need to use the Collections.reverse(list) method in addition. For example:

List<Integer> listIntegers = Arrays.asList(1, 6, 9, 3, 2, 0, 8, 4, 7, 5);

System.out.println("Before sorting: " + listIntegers);

Collections.sort(listIntegers);

System.out.println("After sorting: " + listIntegers);

Collections.reverse(listIntegers);

System.out.println("After reversing: " + listIntegers);
 

Output:

Before sorting: [1, 6, 9, 3, 2, 0, 8, 4, 7, 5]
After sorting: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
After reversing: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
 

NOTES: The reverse(list) method doesn’t sort the list, it just re-order the list’s elements in the reverse order. Therefore the list must be sorted using the sort(list) method before being reversed in order to have the list sorted in descending order.

 

3. Sorting a list whose elements of a custom type

What if a list contains elements of a custom type other than the pre-defined types above? Well, in that case, we have to make the class of the custom type implements the Comparableinterface. Suppose that we have a custom type called Employeeas follows:

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

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

	// getters and setters
}
 

If we try to sort a list whose elements of the type Employeeabove, the sort(list) method will throw a ClassCastException. Now, let’s the Employeeclass implemented the Comparable interface as follows:

public class Employee implements Comparable<Employee> {

	// variables, getters and setters...

	@Override
	public int compareTo(Employee employee) {
		return employee.salary - this.salary;
	}
}
 

As we see, the Employee class now overrides the compareTo() method from the Comparable interface. This method simply compares the salary between this employee and another. And override the toString() method as follows:

public String toString() {
	return String.format("(%s, %d, %d)", name, age, salary);
}
 

We override the toString() method of the Employeeclass so that the returned string will be used when printing the list content.

The following code example creates a list of employees and sorts it based on the descending order of salary:

List<Employee> listEmployees = new ArrayList<Employee>();

listEmployees.add(new Employee("Tom", 45, 80000));
listEmployees.add(new Employee("Sam", 56, 75000));
listEmployees.add(new Employee("Alex", 30, 120000));
listEmployees.add(new Employee("Peter", 25, 60000));

System.out.println("Before sorting: " + listEmployees);

Collections.sort(listEmployees);

System.out.println("After sorting: " + listEmployees); 
 

Output:

Before sorting: [(Tom, 45, 80000), (Sam, 56, 75000), (Alex, 30, 120000), (Peter, 25, 60000)]
After sorting: [(Alex, 30, 120000), (Tom, 45, 80000), (Sam, 56, 75000), (Peter, 25, 60000)]
See the detailed specification of the compareTo() method.

 


4. Sorting a list using a Comparator

The second form of the sort method takes a Comparator implementation that defines the ordering of elements in the list externally:

Collections.sort(list, Comparator)

In this case, the type of the elements need not implement the Comparable interface. This would be useful if we need to sort a list of custom objects which we cannot modify its class; or if we don’t want to rely on the natural ordering of the elements. The following code is example of a comparator that compares two employees based on their ages:

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();
	}
}
 

And the following code snippet sorts a list of employees using the above comparator:

List<Employee> listEmployees = new ArrayList<Employee>();

listEmployees.add(new Employee("Tom", 45, 80000));
listEmployees.add(new Employee("Sam", 56, 75000));
listEmployees.add(new Employee("Alex", 30, 120000));
listEmployees.add(new Employee("Peter", 25, 60000));

System.out.println("Before sorting: " + listEmployees);

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

System.out.println("After sorting: " + listEmployees);
 

Output:

Before sorting: [(Tom, 45, 80000), (Sam, 56, 75000), (Alex, 30, 120000), (Peter, 25, 60000)]
After sorting: [(Peter, 25, 60000), (Alex, 30, 120000), (Tom, 45, 80000), (Sam, 56, 75000)] 
See the detailed specification of the compare() method.

 

API References

 

Related Sorting tutorials:

 

Other Java Collections Tutorials:

 


About the Author:

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.



Attachments:
Download this file (Employee.java)Employee.java[custom type class]0.7 kB
Download this file (EmployeeAgeComparator.java)EmployeeAgeComparator.java[Comparator class]0.3 kB
Download this file (JavaListSortingExamples.java)JavaListSortingExamples.java[Example program]3 kB

Add comment

   


Comments 

#1AlI2017-03-09 09:24
l wish that l read this article before l did my homework assignment for java class online and it very useful article to know how compare and comparator work and also to know how to sort by age and data and so on.
Quote