Sorting Collections with Java Streams API

Examples of sorting various Java collections using Java Streams API sorted() method.

Overview

Java Streams API provides a flexible and readable way to iterate through collection elements and perform various operations. In this tutorial, we’ll explore Steams’s sorted() method, which will use to sort different Java collections. Also, we will explore ways of providing custom sort logic or sorting collections in reversed order.

Please read the Java Streams API Guide to learn more about Java Streams.

Java Streams sorted() Method

Java Streams API provides the sorted() method used for sorting the elements in the Stream. The sorted() method is one of Java Streams API’s Intermediate Operations that comes in two flavours.

Java Streams sorted()

This method does not take any arguments, sorts the elements in the given Stream according to their natural order, and returns a new stream instance.

Stream<T> sorted();Code language: Java (java)

It is important to note that, to use this method for sorting, the elements in the Stream must be Comparable. If the elements in the streams do not implement Comparable, then the method may throw a ClassCastException.

Java Streams sorted(Comparator)

On the other hand, the different flavour of this method accepts a Comparator instance. This method sorts elements in the given Stream according to the provided Comparator implementation.

Stream<T> sorted(Comparator<? super T> comparator);Code language: Java (java)

We can use Comparators to sort collections when we want to keep the comparison logic of the objects.

Sorting a Java Stream

Let’s use the sorted() method of the Stream to sort a Java Collection element in the natural order of its elements. Before that, let’s consider we have a Student class like this.

public class Student {
  private final Long studentId;
  private final String firstName;
  private final String lastName;
  private final Integer age;

  //Constructors, Getter, and Setter methods
}Code language: Java (java)

Let’s create a few dummy students and put them in a Collection.

Student student1 = new Student(2L, "Karl", "A", 18);
Student student2 = new Student(3L, "Jack", "P", 20);
Student student3 = new Student(5L, "Nick", "G", 17);
Student student4 = new Student(1L, "Tom", "A", 22);
Student student5 = new Student(4L, "Jon", "E", 22);

Collection<Student> students = new HashSet<>();
students.add(student1);
students.add(student2);
students.add(student3);
students.add(student4);
students.add(student5);Code language: Java (java)

Note that we have created a HashSet of student instances. However, you may use any other collection implementation as well.

Example of sorting a Java Collection using Stream’s sorted() method.

List<String> firstNames = students.stream()
  .map(Student::getFirstName)
  .sorted()
  .toList();

System.out.println(firstNames);
//prints:
//[Jack, Jon, Karl, Nick, Tom]Code language: Java (java)

We created a Stream of a Java Collection and sorted the Student names in their natural form, i.e. alphabetically.

Sorting a Stream of Custom Objects

We can also sort a Stream of custom elements using Java Streams, for example, a stream of our Student objects. However, our custom object does not implement Comparable. Thus, we need to provide our comparison logic as a Comparator.

Example of sorting a Stream of custom objects using Stream sorted() method with Comparator.

List<Student> sorted = students.stream()
  .sorted(Comparator.comparing(Student::getFirstName))
  .toList();

sorted.forEach(System.out::println);
//prints:
//Student(studentId=3, firstName=Jack, lastName=P, age=20)
//Student(studentId=4, firstName=Jon, lastName=E, age=22)
//Student(studentId=2, firstName=Karl, lastName=A, age=18)
//Student(studentId=5, firstName=Nick, lastName=G, age=17)
//Student(studentId=1, firstName=Tom, lastName=A, age=22)Code language: Java (java)

We used a Java Lambda expression-based Comparator implementation to sort a collection of objects. In the end, we collect the sorted objects in a List.

Reverse Sorting with Java Streams

By default, both Java Stream sorted() methods sort the elements in the forward or ascending order. To sort a stream in the descending order of the elements, we need to provide a reverse Comparator.

For example, let’s sort a stream of elements in the descending natural order.

List<String> firstNames = students.stream()
  .map(Student::getFirstName)
  .sorted(Comparator.reverseOrder())
  .toList();

System.out.println(firstNames);
//prints:
//[Tom, Nick, Karl, Jon, Jack]Code language: Java (java)

Passing a reversed comparator, we can reverse the natural sort order. The same is evident from the output.

Similarly, we can sort a collection of custom objects in reverse order. To do that, we need to choose a reversed Comparator.

List<Student> sorted = students.stream()
  .sorted(Comparator.comparing(Student::getFirstName).reversed())
  .toList();

sorted.forEach(System.out::println);
//prints:
//Student(studentId=1, firstName=Tom, lastName=A, age=22)
//Student(studentId=5, firstName=Nick, lastName=G, age=17)
//Student(studentId=2, firstName=Karl, lastName=A, age=18)
//Student(studentId=4, firstName=Jon, lastName=E, age=22)
//Student(studentId=3, firstName=Jack, lastName=P, age=20)Code language: Java (java)

And the results will be in the descending order of the student’s first name.

Sorting a Stream of Java Map

Like any Collection, we can also use Java Steams API to sort Java Map. We will quickly see code examples of doing that here. If you are more interested in Sorting Java HashMaps, consider reading – Sort Java HashMap by Key or Value.

Sort based on the key

List<Long> studentIds = studentMap.keySet().stream()
  .sorted()
  .toList();Code language: Java (java)

Here, we are extracting a set of all keys from the map and creating a stream. Thus, the Stream it generates is a stream of Long values. That is why we can sort the elements using natural order.

Alternatively, let’s see sorting based on the Value.

List<Student> studentIds = studentMap.values().stream()
  .sorted(Comparator.comparing(Student::getFirstName))
  .toList();Code language: PHP (php)

We are creating a stream of values, i.e. Students and using a Comparator to sort based on the first name.

Summary

This was a quick tutorial on using Java Streams sorted() method. We first understood the two forms of this method. The first form can sort elements in the Stream by their natural order. However, to do so, the elements must be of Comparable type. Else, the sorted() method throws ClassCastException.

The second sorted() method accepts a Comparator, where we can plug in our comparison logic. This method helps sort objects that are not Comparable. Also, we learned to change the sorting order of the elements to achieve descending order.

For a complete source of the examples used here, please visit our GitHub Repository.

Related Posts: