Hi all, in this article, we will learn Java Streams Comparators like Comparator.comparing(), Comparator.naturalOrder(), Comparator.reverseOrder(), etc. The Comparator Interface provides us comparison and sorting options that we can use with Java Streams. Let’s start to do some examples and learn these tricks.
Java Streams Comparators with Examples
We will start with Sorting with Comparator examples then we will see Comparator.comparing() examples.
Sorting with Comparator Natural Order and Reverse Order
Let’s start with some sorting examples. We can use the Comparator interface’s naturalOrder() and reverseOrder() method to sort the elements of a stream in Ascending and Descending order.
- naturalOrder() equals to Ascending Order
- reverseOrder() equals to Descending Order
@TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class StreamSorted { List<Integer> numbers = new ArrayList<>(); @BeforeEach public void setup(TestInfo testInfo) { System.out.println("Test name: " + testInfo.getDisplayName()); numbers.add(5); numbers.add(8); numbers.add(3); numbers.add(7); numbers.add(2); numbers.add(6); numbers.add(1); numbers.add(10); numbers.add(9); numbers.add(4); } @AfterEach public void tearDown() { numbers.clear(); System.out.println(""); } /** * Natural sort is Ascending Sort */ @Test @Order(1) public void streamNaturalOrderSortTest() { numbers.stream() .peek(number -> System.out.println("Filter operation for number: " + number)) //Peek is used for debugging purposes. .filter(number -> number % 2 == 1) //Filter the odd numbers .sorted(Comparator.naturalOrder()) //Natural order of sorting. (Ascending Sort) .limit(4) //After 4th element stop the stream. Process first 4 element. .peek(number -> System.out.println("Map operation for number: " + number)) //Peek is used for debugging purposes. .map(number -> number * 2) //Transform the number to number*2 .forEach(number -> System.out.println("Result of stream: " + number)); //Print the results. } /** * Reverse sort is Descending Sort */ @Test @Order(2) public void streamReverseOrderSortTest() { numbers.stream() .peek(number -> System.out.println("Filter operation for number: " + number)) //Peek is used for debugging purposes. .filter(number -> number % 2 == 1) //Filter the odd numbers .sorted(Comparator.reverseOrder()) //Reverse order of sorting. (Descending Sort) .limit(4) //After 4th element stop the stream. Process first 4 element. .peek(number -> System.out.println("Map operation for number: " + number)) //Peek is used for debugging purposes. .map(number -> number * 2) //Transform the number to number*2 .forEach(number -> System.out.println("Result of stream: " + number)); //Print the results. } }
Outputs
NaturalOrder Test Output
The test code:
- Prints the debugging texts with peek().
- Filters the odd numbers.
- Then, sorts all elements with Natural Order which is Ascending Order.
- With limit(4), when the 4th odd number is filtered which is “1”, it does not continue to do operations for other elements.
- Prints the debugging texts with peek(),
- Transform the elements to (elements*2).
- Prints the results with forEach().
ReverseOrder Test Output
The test code:
- Prints the debugging texts with peek().
- Filters the odd numbers.
- Then, sorts all elements with Reverse Order which is Descending Order.
- With limit(4), when the 4th odd number is filtered which is “1”, it does not continue to do operations for other elements.
- Prints the debugging texts with peek(),
- Transform the elements to (elements*2).
- Prints the results with forEach().
Java Streams Comparator.comparing() Examples
The Comparator Interface provides us several comparisons and sorting options as seen below screenshot. We have already learned the reverseOrder() and naturalOrder() sorting with the Comparator Interface.
Now, let’s do some examples with Comparator.comparing(). We have a Footballer class which contains the footballer’s name, team, and age. We can do comparisons on each element of the footballers by using comparator.comparing() method. We can find the footballer who has minimum age or the footballer who has maximum age etc.
Footballer Class
I used Lombok library’s Getter, Setter, and AllArgConstructor annotations to construct the Footballer class.
@Setter @Getter @AllArgsConstructor public class Footballer { String name; String team; int age; @Override public String toString() { return "Footballer{" + "name='" + name + '\'' + ", team='" + team + '\'' + ", age=" + age + '}'; } }
and now time to write some tests to see Comparator.comparing() in action. In our examples, we will find the youngest and eldest football players.
public class ComparatorExamples { List<Footballer> footballers = new ArrayList<>(); @BeforeEach public void setup() { Footballer ronaldo = new Footballer("Ronaldo", "Manchester United", 36); Footballer messi = new Footballer("Messi", "Paris Saint German", 33); Footballer ozil = new Footballer("Ozil", "Fenerbahce", 32); footballers.add(ronaldo); footballers.add(messi); footballers.add(ozil); } /** * Comparator.comparing example */ @Test public void comparatorComparingTest() { Optional<Footballer> youngestFootballer = footballers.stream() .min(Comparator.comparing(Footballer::getAge)); Optional<Footballer> eldestFootballer = footballers.stream() .max(Comparator.comparing(Footballer::getAge)); youngestFootballer.ifPresent(footballer -> System.out.println("Youngest Footballer: " + footballer)); eldestFootballer.ifPresent(footballer -> System.out.println("Eldest Footballer: " + footballer)); } }
Output
As you see below, by using Comparator.comparing() inside Stream’s min() and max() methods, we can easily find the youngest and eldest football players. Min and max method’s return type is Optional that’s why I wrapped the Footballer class with Optional. I will explain Optional class details in another article. Simply, it will help us not to get null pointer exceptions in Java.
GitHub Project
In this article, I shared with you the most common usages of the Comparator Interface in Java. I hope you enjoyed reading it. See you in the next articles.
Thanks for reading,
Onur Baskirt

Onur Baskirt is a Software Engineering Leader with international experience in world-class companies. Now, he is a Software Engineering Lead at Emirates Airlines in Dubai.