Java Stream sorted
last modified May 24, 2025
This article delves into the Java Stream sorted
method, a versatile
tool for ordering elements within a stream. It enables developers to arrange
data, such as numbers, strings, or custom objects, in a specified order, making
it an essential feature for processing collections in a functional programming
style.
The sorted method is an intermediate operation in the Java Stream API
that produces a new stream with the elements of the original stream arranged in
a defined order. As a stateful operation, it must process the entire stream to
determine the correct sequence, which may impact performance for large datasets.
It supports sorting in natural order for elements that implement
Comparable
or in a custom order defined by a provided
Comparator
.
Basic sorted syntax
The sorted method has two variants:
Stream<T> sorted() Stream<T> sorted(Comparator<? super T> comparator)
The first variant, sorted
, arranges elements in their natural
order, requiring that the elements implement the Comparable
interface, such as strings (sorted alphabetically) or numbers (sorted
numerically). If the elements do not implement Comparable
, a
runtime exception occurs.
The second variant, sorted(Comparator)
, allows for custom sorting
logic using a provided Comparator
, enabling flexible ordering, such
as reverse sorting or sorting by specific object properties. This makes it
suitable for complex sorting requirements. Both variants return a new stream,
leaving the original data source unchanged, and are optimized for parallel
processing, though developers should be mindful of memory usage with large
streams due to the stateful nature of the operation.
Natural ordering of numbers
Sorting numbers using natural order.
void main() { Stream<Integer> numbers = Stream.of(5, 3, 8, 1, 2, 7, 4, 6); numbers.sorted() .forEach(System.out::println); }
This example sorts integers in ascending order using their natural ordering. The
sorted
method without arguments relies on the elements implementing
Comparable
.
Reverse order sorting
Sorting elements in reverse order using Comparator.reverseOrder
.
void main() { Stream<String> words = Stream.of("banana", "apple", "pear", "orange"); words.sorted(Comparator.reverseOrder()) .forEach(System.out::println); }
This example sorts strings in reverse alphabetical order. The
Comparator.reverseOrder
method returns a comparator that imposes
the reverse of natural ordering.
$ java Main.java pear orange banana apple
Custom object sorting
In the following example, we will sort custom objects using a
Comparator
. This is a common scenario when dealing with collections
of user-defined types, such as sorting a list of people by their age or name.
record Person(String firstName, String lastName, String occupation) { } void main() { Stream<Person> people = Stream.of( new Person("John", "Doe", "Engineer"), new Person("Jane", "Smith", "Doctor"), new Person("Alice", "Johnson", "Artist"), new Person("Bob", "Brown", "Engineer"), new Person("Charlie", "Davis", "Teacher"), new Person("Diana", "Wilson", "Artist") ); people.sorted(Comparator.comparing(Person::occupation)) .forEach(p -> System.out.println(p)); }
This example sorts Person
objects by their occupation using a
Comparator
. The comparing
method creates a comparator
that compares Person
objects based on the specified property,
which in this case is the occupation.
$ java Main.java Person[firstName=Alice, lastName=Johnson, occupation=Artist] Person[firstName=Diana, lastName=Wilson, occupation=Artist] Person[firstName=Jane, lastName=Smith, occupation=Doctor] Person[firstName=John, lastName=Doe, occupation=Engineer] Person[firstName=Bob, lastName=Brown, occupation=Engineer] Person[firstName=Charlie, lastName=Davis, occupation=Teacher]
This example demonstrates how to sort Person
objects by their
date of birth.
record Person(String firstName, String lastName, String dob) { public int age() { return Period.between(LocalDate.parse(dob), LocalDate.now()).getYears(); } } void main() { Stream<Person> people = Stream.of( new Person("John", "Doe", "1987-01-01"), new Person("Jane", "Smith", "1990-05-15"), new Person("Alice", "Johnson", "2000-03-20"), new Person("Bob", "Brown", "1995-07-30"), new Person("Charlie", "Davis", "1980-12-10"), new Person("Diana", "Wilson", "2002-11-25") ); people.sorted(Comparator.comparing(Person::dob)) .forEach(p -> System.out.println(p)); }
This example sorts Person
objects by their date of birth (dob).
The comparing
method creates a comparator that compares
Person
objects based on the specified property, which in this case is
the date of birth. The dob
field is expected to be in the format
yyyy-MM-dd
, allowing for correct chronological sorting.
Multiple sort criteria
In the next example we sort a list of employees by multiple criteria: department, salary, and name.
record Employee(String name, String department, double salary) { } void main() { Stream<Employee> employees = Stream.of( new Employee("Alice", "HR", 75000), new Employee("Bob", "IT", 80000), new Employee("Charlie", "IT", 75000), new Employee("Diana", "HR", 80000) ); employees.sorted(Comparator.comparing(Employee::department) .thenComparing(Employee::salary) .thenComparing(Employee::name)) .forEach(e -> System.out.println( e.department() + " - " + e.salary() + " - " + e.name())); }
This example sorts employees first by department, then by salary, and finally by
name. The thenComparing
method allows chaining multiple
comparators.
$ java Main.java HR - 75000.0 - Alice HR - 80000.0 - DianathenComparing IT - 75000.0 - Charlie IT - 80000.0 - Bob
Case-insensitive string sorting
In the next example, we will sort strings in a case-insensitive manner.
void main() { Stream<String> mixedCase = Stream.of("apple", "Banana", "cherry", "Date"); mixedCase.sorted(String.CASE_INSENSITIVE_ORDER) .forEach(System.out::println); }
This example sorts strings ignoring case differences. The
String.CASE_INSENSITIVE_ORDER
comparator provides case-insensitive
comparison of strings.
$ java Main.java apple Banana cherry Date
Sorting with null values
The next example demonstrates how to handle null values in sorting using
Comparator.nullsFirst
and Comparator.nullsLast
.
void main() { Stream<String> withNulls = Stream.of("banana", null, "apple", null, "cherry"); System.out.println("Nulls first:"); withNulls.sorted(Comparator.nullsFirst(Comparator.naturalOrder())) .forEach(System.out::println); System.out.println("\nNulls last:"); Stream<String> withNulls2 = Stream.of("banana", null, "apple", null, "cherry"); withNulls2.sorted(Comparator.nullsLast(Comparator.naturalOrder())) .forEach(System.out::println); }
This example demonstrates handling null values in sorting.
nullsFirst
places nulls before non-null elements, while
nullsLast
places them after.
$ java Main.java Nulls first: null null apple banana cherry Nulls last: apple banana cherry null null
Source
Java Stream sorted documentation
In this article we have explored the Java Stream sorted
method. It
provides flexible options for ordering stream elements using natural ordering or
custom comparators. Understanding sorting is essential for effective stream
processing and data manipulation in Java.
Author
List all Java tutorials.