Overview

In Java 8, some new comparison utility methods are added in the Comparator interface which returns the behavior of Comparator. those methods can be used with lambda expression or we can pass Comparator to Stream.sorted(Comparator comparator) method to compare and sort the stream elements as per behavior of specified Comparator implementation. Comparator interface also has static methods which returns already implemented Comparator behavior that can be used to sort the stream elements in natural order, in reverse of natural order etc. Let’s see Java sort using Comparator example with Stream.sorted() method to sort a list of primitive-wrapper and custom java type.

Note: For normal streams, the sort method is stable, but for parallel streams, no guarantee of stability.

Example 1: Sort List of Integer in Ascending Order

In the following example, going to use the list of integer type from 0 to 9 to demonstrate how to sort and print element of that list in natural (ascending) order using Stream.sorted() and Comparator interface.

List<Integer> integers = Arrays.asList(2, 9, 5, 8, 1, 4, 3, 7, 0, 6);
integers.stream()
    .sorted(Comparator.naturalOrder()) //Compare integer stream collection elements and return in ascending order
    //.sorted(Comparator.comparingInt(Integer::intValue))
    //.sorted()
    .forEach(System.out::println);

Output

0
1
2
3
4
5
6
7
8
9

Example 2: Sort List of Integer in Descending Order

In the following example, going to use the same list as in the previous example for demonstrating how to sort and print those list elements in reverse (descending) order with the help of Stream.sorted() and Comparator.reverseOrder() methods.

List<Integer> integers = Arrays.asList(2, 9, 5, 8, 1, 4, 3, 7, 0, 6);
integers.stream()
    .sorted(Comparator.reverseOrder()) // Compare integer stream elements and return in descending order
    .forEach(System.out::println);

Output

9
8
7
6
5
4
3
2
1
0

Example 3: Sort List of Date

In the following example, we are going to demonstrate how to sort and print List of Date in ascending and descending order:

Calendar date = new Calendar.Builder().build();
List<Date> dates = new ArrayList<>();
date.set(1900, Calendar.FEBRUARY, 10);
dates.add(date.getTime());
date.set(2000, Calendar.MAY, 10);
dates.add(date.getTime());
date.set(1900, Calendar.MARCH, 5);
dates.add(date.getTime());
date.set(2000, Calendar.MAY, 5);
dates.add(date.getTime());
date.set(1900, Calendar.FEBRUARY, 1);
dates.add(date.getTime());
System.out.println("# Before sorting");
dates.forEach(System.out::println);
System.out.println("# After sorting in ascending order");
dates.stream()
        .sorted()
        .forEach(System.out::println);
System.out.println("# After sorting in descending order");
dates.stream()
        .sorted(Comparator.reverseOrder())

Output

# Before sorting
Sat Feb 10 00:00:00 IST 1900
Wed May 10 00:00:00 IST 2000
Mon Mar 05 00:00:00 IST 1900
Fri May 05 00:00:00 IST 2000
Thu Feb 01 00:00:00 IST 1900
# After sorting in ascending order
Thu Feb 01 00:00:00 IST 1900
Sat Feb 10 00:00:00 IST 1900
Mon Mar 05 00:00:00 IST 1900
Fri May 05 00:00:00 IST 2000
Wed May 10 00:00:00 IST 2000
# After sorting in descending order
Wed May 10 00:00:00 IST 2000
Fri May 05 00:00:00 IST 2000
Mon Mar 05 00:00:00 IST 1900
Sat Feb 10 00:00:00 IST 1900
Thu Feb 01 00:00:00 IST 1900

 

Example 4: Sort Custom Object by its attributes

In the previous example we have learned, how to sort a list of wrapper type, now going to sort a list of a custom object based on its one or more attributes in the following example:

Let’s consider following Employee POJO as a custom class

package com.javadeveloperzone;
public class Employee {
    private int id;
    private String name;
    private short age;
    public Employee(int id, String name, short age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
    public int getId() {
        return id;
    }
    public String getName() {
        return name;
    }
    public short getAge() {
        return age;
    }
}

See the following example of how to sort given list of employees by age using comparing() method (accepts a function that extracts a sort key from an Employee) of Comparator interface

List<Employee> employees = new ArrayList<>(); 
employees.add(new Employee(1, "Shyam", (short) 35)); 
employees.add(new Employee(2, "Arjun", (short) 22)); 
employees.add(new Employee(3, "Karan", (short) 30)); 
employees.add(new Employee(4, "Anil", (short) 35)); 
employees.add(new Employee(5, "Arjun", (short) 20));
employees.stream()
    .sorted(Comparator.comparing(Employee::getAge))
    .forEach(employee -> System.out.println(employee.getName()));

Output

20: Arjun
22: Arjun
30: Karan
35: Shyam  //Employee Shyam come just before the Anil due to both age is same and in list Shyam added first
35: Anil

Comparator interface has another useful method thenComparing(), that returns a lexicographic-order comparator composed of this and then the sort key.

Let’s see how to sort employee list by multiple fields: age and name, using thenComparing() method

List<Employee> employees = new ArrayList<>();
employees.add(new Employee(1, "Shyam", (short) 35)); 
employees.add(new Employee(2, "Arjun", (short) 22)); 
employees.add(new Employee(3, "Karan", (short) 30)); 
employees.add(new Employee(4, "Anil", (short) 35)); 
employees.add(new Employee(5, "Arjun", (short) 20));
employees.stream()
        .sorted(Comparator.comparing(Employee::getAge).thenComparing(Employee::getName))
        .forEach(employee -> System.out.println(employee.getAge() + ": " + employee.getName()));

Output

20: Arjun
22: Arjun
30: Karan
35: Anil    //Employee Anil come just before the Shyam due to sort by name after sorting by age
35: Shyam

Conclusion:

In this article, we have learned, how to sort a list of primitive-wrapper and custom Java type by Java sort using Comparator example. also, covered how to do sorting on multiple attributes of the custom object with the help of Comparator.thenComparing().

References

Was this post helpful?

Leave a Reply

Your email address will not be published. Required fields are marked *