In this article, we will discuss how to sort list of primitive int, String & Custom Objects in Java 1.8 version.
1. Stream sorted() method
- This Stream method is an intermediate operation which sorts elements present in the stream according to natural order
- If elements present in the stream aren’t Comparable then java.lang.ClassCastException is thrown when final terminal operation is executed
- For ordered streams, the sort is stable
- For unordered streams, no stability guarantees are made.
- Stream’s sorted() method is stateful
- Another intermediate operation can be applied to returned stream for example filter(), map(), distinct() methods can be applied after sorted() operation
- Method signature :- Stream<T> sorted()
1.1 Sorting List of Primitive int
- Here, there are first 10 natural numbers in random order
- We are sorting these integer numbers in natural order (or ascending order) using Java 8 Stream’s sorted() method
- Lambda expression – finally, printing sorted numbers using Java 8 Stream’s forEach() method to console
SortingPrimitiveIntNumbers.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | package net.bench.resources.stream.sorted.example; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class SortingPrimitiveIntNumbers { public static void main(String[] args) { // 1. List - 1st 10 natural numbers in random order List<Integer> numbers = Arrays.asList( 7 , 3 , 10 , 1 , 8 , 4 , 6 , 5 , 2 , 9 ); // pretty print numbers in random order System.out.println( "1. Original List of Integer numbers in random order :\n" ); numbers.forEach(num -> System.out.print(num + "\t" )); // 2. sorting using Stream's sorted() method List<Integer> sortedIntNumbers = numbers // original source elements .stream() // 2.1 get sequential stream .sorted() // 2.2 sort acc. to natural order .collect(Collectors.toList()); // 2.3 collect to new list after sorting // pretty printing to console System.out.println( "\n\n\n2. Sorted integer numbers in Ascending order : \n" ); sortedIntNumbers.forEach(num -> System.out.print(num + "\t" )); } } |
Output:
1 2 3 4 5 6 7 8 | 1 . Original List of Integer numbers in random order : 7 3 10 1 8 4 6 5 2 9 2 . Sorted integer numbers in Ascending order : 1 2 3 4 5 6 7 8 9 10 |
1.2 Sorting List of String Objects
- Here, 1st we are defining few String elements in List
- Then we are sorting these String elements in natural order (or alphabetical order) using Java 8 Stream’s sorted() method
- Method reference – finally, printing sorted String elements using Java 8 Stream’s forEach() method to console
SortingStringObjects.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | package net.bench.resources.stream.sorted.example; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class SortingStringObjects { public static void main(String[] args) { // 1. List of String elements List<String> companies = Arrays.asList( "Infosys" , "Capgemini" , "Hexaware" , "LTI" , "Accenture" ); // pretty print to console System.out.println( "1. Original List of String :\n" ); companies.forEach(System.out::println); // 2. sorting using Stream's sorted() method List<String> sortedCompanyNames = companies // original source elements .stream() // 2.1 get sequential stream .sorted() // 2.2 sorting alphabetical order of String elements .collect(Collectors.toList()); // 2.3 collect to new list after sorting // pretty print to console System.out.println( "\n2. Sorted Company Names in Alphabetical order : \n" ); sortedCompanyNames.forEach(System.out::println); } } |
Output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 1 . Original List of String : Infosys Capgemini Hexaware LTI Accenture 2 . Sorted Company Names in Alphabetical order : Accenture Capgemini Hexaware Infosys LTI |
2. Stream sorted(Comparator) method
- This Stream method is an intermediate operation which sorts elements present in the stream according to Comparator provided
- This Comparator logic can be either in natural order or reverse order depending upon our business requirement
- For ordered streams, the sort is stable
- For unordered streams, no stability guarantees are made.
- Stream’s sorted(Comparator) method is stateful
- Method signature :- Stream<T> sorted(Comparator<? super T> comparator)
2.1 Sorting List of Custom Objects
- Here, we are adding Player objects with 4 attributes (Id, Name, Average, Rank) to List object
- Example-1 : sorting Player objects according to Id in natural order using Comparator p1, p2 -> p1.getId() – p2.getId(); and printing to console using lambda expression
- Example-2 : sorting Player objects according to Name in alphabetical order using Comparator p1, p2 -> p1.getName() .compare(p2.getName()); and printing to console using lambda expression
- Example-3 : sorting Player objects according to Rank in natural order using Comparator p1, p2 -> p1.getRank() – p2.getRank(); and printing to console using lambda expression
Player.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class Player { // private member variables private int id; private String name; private double average; private int rank; // public 4-arg parameterized constructor // getter and setters // override toString() method } |
SortingCustomObjects.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | package net.bench.resources.stream.sorted.example; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class SortingCustomObjects { public static void main(String[] args) { // 1. List of Student objects List<Player> fab5IndianOrder = Arrays.asList( new Player( 1 , "Dravid" , 88.55 , 2 ), new Player( 2 , "Sehwag" , 55.65 , 5 ), new Player( 3 , "Laxman" , 77.75 , 3 ), new Player( 4 , "Sachin" , 99.25 , 1 ), new Player( 5 , "Sourav" , 66.15 , 4 ) ); // 1. unsorted players by any attributes - original list System.out.println( "1. List of unsorted Players" + " in orginal list :\n" ); fab5IndianOrder.forEach(System.out::println); // 2. Natural sorting acc. to Player's Id List<Player> sortedById = fab5IndianOrder // original source .stream() // 2.1 get sequential stream .sorted((p1, p2) -> p1.getId() - p2.getId()) // 2.2 sort by Id .collect(Collectors.toList()); // 2.3 collect to new List // pretty print to console using lambda expression System.out.println( "\n\n2. Players sorted acc. to" + " Natural order of Id :\n" ); sortedById.forEach(playerById -> System.out.println(playerById)); // 3. Natural sorting acc. to Player's Name List<Player> sortedByName = fab5IndianOrder // original source .stream() // 3.1 get sequential stream .sorted((p1, p2) -> p1.getName() .compareTo(p2.getName())) // 3.2 sort by Name .collect(Collectors.toList()); // 3.3 collect to new List // pretty print to console using lambda expression System.out.println( "\n\n3. Players sorted acc. to" + " Alphabetical order of Name :\n" ); sortedByName.forEach(playerByName -> System.out.println(playerByName)); // 4. Natural sorting acc. to Player's Rank List<Player> sortedByRank = fab5IndianOrder // original source .stream() // 4.1 get sequential stream .sorted((p1, p2) -> Integer .compare(p1.getRank(), p2.getRank())) // 4.2 Rank sort .collect(Collectors.toList()); // 4.3 collect to new List // pretty print to console using lambda expression System.out.println( "\n\n4. Players sorted acc. to" + " Natural order of Rank :\n" ); sortedByRank.forEach(playerByRank -> System.out.println(playerByRank)); } } |
Output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | 1 . List of unsorted Players in orginal list : Player [id= 1 , name=Dravid, average= 88.55 , rank= 2 ] Player [id= 2 , name=Sehwag, average= 55.65 , rank= 5 ] Player [id= 3 , name=Laxman, average= 77.75 , rank= 3 ] Player [id= 4 , name=Sachin, average= 99.25 , rank= 1 ] Player [id= 5 , name=Sourav, average= 66.15 , rank= 4 ] 2 . Players sorted acc. to Natural order of Id : Player [id= 1 , name=Dravid, average= 88.55 , rank= 2 ] Player [id= 2 , name=Sehwag, average= 55.65 , rank= 5 ] Player [id= 3 , name=Laxman, average= 77.75 , rank= 3 ] Player [id= 4 , name=Sachin, average= 99.25 , rank= 1 ] Player [id= 5 , name=Sourav, average= 66.15 , rank= 4 ] 3 . Players sorted acc. to Alphabetical order of Name : Player [id= 1 , name=Dravid, average= 88.55 , rank= 2 ] Player [id= 3 , name=Laxman, average= 77.75 , rank= 3 ] Player [id= 4 , name=Sachin, average= 99.25 , rank= 1 ] Player [id= 2 , name=Sehwag, average= 55.65 , rank= 5 ] Player [id= 5 , name=Sourav, average= 66.15 , rank= 4 ] 4 . Players sorted acc. to Natural order of Rank : Player [id= 4 , name=Sachin, average= 99.25 , rank= 1 ] Player [id= 1 , name=Dravid, average= 88.55 , rank= 2 ] Player [id= 3 , name=Laxman, average= 77.75 , rank= 3 ] Player [id= 5 , name=Sourav, average= 66.15 , rank= 4 ] Player [id= 2 , name=Sehwag, average= 55.65 , rank= 5 ] |
3. Reverse sorting
- This section covers example for sorting primitive int, String & Custom Objects in reverse order by passing Comparator
- We can build logic around Comparator to sort elements in either natural order or reverse order
- Comparator.naturalOrder() helps to sort in natural order, if the objects are Comparable otherwise java.lang.ClassCastException is thrown
- Comparator.reverseOrder() helps to sort in reverse order, if the objects are Comparable otherwise java.lang.ClassCastException is thrown
3.1 Reverse sorting List of Primitive int
- This example has list of integer numbers
- we are sorting in natural & reverse order using Comparator.naturalOrder() i.e.; in ascending order & Comparator.reverseOrder() i.e.; in descending order respectively
- Lambda expression – finally, printing sorted Student objects using Java 8 Stream’s forEach() method to console
ReverseSortingPrimitiveIntNumbers.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | package net.bench.resources.stream.sorted.example; import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; public class ReverseSortingPrimitiveIntNumbers { public static void main(String[] args) { // 1. List - 10 numbers in random order List<Integer> numbers = Arrays.asList( 35 , 15 , 10 , 5 , 50 , 20 , 45 , 30 , 25 , 40 ); // pretty print numbers in random order System.out.println( "1. Original List of" + " Integer numbers in Random order :\n" ); numbers.forEach( randomOrderNumber -> System.out.print(randomOrderNumber + "\t" )); // 2. Ascending sorting using Stream.sorted() method List<Integer> sortedIntNumbers = numbers // original source elements .stream() // 2.1 get sequential stream .sorted(Comparator.naturalOrder()) // 2.2 sort acc. to natural order .collect(Collectors.toList()); // 2.3 collect to new list after sorting // pretty printing to console System.out.println( "\n\n\n2. Natural sorting - Ascending order : \n" ); sortedIntNumbers.forEach( ascendingOrderNumber -> System.out.print(ascendingOrderNumber + "\t" )); // 3. Descending sorting using Stream.sorted() method List<Integer> reverseNumbers = numbers // original source elements .stream() // 3.1 get sequential stream .sorted(Comparator.reverseOrder()) // 3.2 reverse sorting .collect(Collectors.toList()); // 3.3 collect to new list after sorting // pretty printing to console System.out.println( "\n\n\n3. Reverse sorting - Descending order : \n" ); reverseNumbers.forEach( descendingOrderNumber -> System.out.print(descendingOrderNumber + "\t" )); } } |
Output:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 1 . Original List of Integer numbers in Random order : 35 15 10 5 50 20 45 30 25 40 2 . Natural sorting - Ascending order : 5 10 15 20 25 30 35 40 45 50 3 . Reverse sorting - Descending order : 50 45 40 35 30 25 20 15 10 5 |
3.2 Reverse sorting List of String elements
- This example has list of String elements
- we are sorting in natural & reverse order using Comparator.naturalOrder() i.e.; in alphabetical order and Comparator.reverseOrder() respectively
- Lambda expression – finally, printing sorted Student objects using Java 8 Stream’s forEach() method to console
ReverseSortingStringObjects.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | package net.bench.resources.stream.sorted.example; import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; public class ReverseSortingStringObjects { public static void main(String[] args) { // 1. List of String elements List<String> companies = Arrays.asList( "Infosys" , "Capgemini" , "Hexaware" , "LTI" , "Accenture" ); // pretty print to console System.out.println( "1. Original List of String :\n" ); companies.forEach(System.out::println); // 2. natural sorting using Stream's sorted() method List<String> sortedCompanyNames = companies // original source .stream() // 2.1 get sequential stream .sorted(Comparator.naturalOrder()) // 2.2 sorting alphabetical order .collect(Collectors.toList()); // 2.3 collect to new list // pretty print to console System.out.println( "\n2. Sorted by Company Names in Alphabetical order : \n" ); sortedCompanyNames.forEach(System.out::println); // 3. reverse sorting using Stream's sorted() method List<String> reverseSorting = companies // original source .stream() // 3.1 get sequential stream .sorted(Comparator.reverseOrder()) // 3.2 reverse sorting .collect(Collectors.toList()); // 3.3 collect to new list // pretty print to console System.out.println( "\n3. Reverse Sorting of String elements : \n" ); reverseSorting.forEach(System.out::println); } } |
Output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 1 . Original List of String : Infosys Capgemini Hexaware LTI Accenture 2 . Sorted by Company Names in Alphabetical order : Accenture Capgemini Hexaware Infosys LTI 3 . Reverse Sorting of String elements : LTI Infosys Hexaware Capgemini Accenture |
3.3 Reverse sorting List of Custom Objects
- This example has list of Student objects
- We are sorting Student objects based on all 4 attributes Id, Name, Rank & Average in reverse order
- Reverse Id sorting – (p1, p2) -> p2.getId() – p1.getId();
- Reverse Name sorting – (p1, p2) -> p2.getName().compareTo(p1.getName());
- Reverse Rank sorting – (p1, p2) -> Integer.compare(p2.getRank(), p1.getRank());
- Reverse Average sorting – (p1, p2) -> Double.compare(p2.getAverage(), p1.getAverage());
- Lambda expression – finally, printing sorted Student objects using Java 8 Stream’s forEach() method to console
ReverseSortingCustomObjects.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | package net.bench.resources.stream.sorted.example; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class ReverseSortingCustomObjects { public static void main(String[] args) { // 1. List of Student objects List<Player> fab5IndianOrder = Arrays.asList( new Player( 4 , "Sachin" , 99.25 , 1 ), new Player( 1 , "Dravid" , 88.55 , 2 ), new Player( 2 , "Sehwag" , 55.65 , 5 ), new Player( 5 , "Sourav" , 66.15 , 4 ), new Player( 3 , "Laxman" , 77.75 , 3 ) ); // 1. unsorted players by any attributes - original list System.out.println( "1. UNSORTED Players in orginal list :\n" ); fab5IndianOrder.forEach(System.out::println); // 2. REVERSE sorting acc. to Player's Id List<Player> sortedById = fab5IndianOrder // original source .stream() // 2.1 get sequential stream .sorted((p1, p2) -> p2.getId() - p1.getId()) // 2.2 Id sort .collect(Collectors.toList()); // 2.3 collect to new List // pretty print to console using lambda expression System.out.println( "\n\n2. REVERSE sorting of Players by Id :\n" ); sortedById.forEach(playerById -> System.out.println(playerById)); // 3. REVERSE sorting acc. to Player's Name List<Player> sortedByName = fab5IndianOrder // original source .stream() // 3.1 get sequential stream .sorted((p1, p2) -> p2.getName() .compareTo(p1.getName())) // 3.2 Name sort .collect(Collectors.toList()); // 3.3 collect to new List // pretty print to console using lambda expression System.out.println( "\n\n3. REVERSE sorting of Players by Name :\n" ); sortedByName.forEach(playerByName -> System.out.println(playerByName)); // 4. REVERSE sorting acc. to Player's Rank List<Player> sortedByRank = fab5IndianOrder // original source .stream() // 4.1 get sequential stream .sorted((p1, p2) -> Integer .compare(p2.getRank(), p1.getRank())) // 4.2 Rank sort .collect(Collectors.toList()); // 4.3 collect to new List // pretty print to console using lambda expression System.out.println( "\n\n4. REVERSE sorting of Players by Rank :\n" ); sortedByRank.forEach(playerByRank -> System.out.println(playerByRank)); // 5. REVERSE sorting acc. to Player's Average List<Player> sortedByAverage = fab5IndianOrder // original source .stream() // 5.1 get sequential stream .sorted((p1, p2) -> Double .compare(p2.getAverage(), p1.getAverage())) // 5.2 Average sort .collect(Collectors.toList()); // 5.3 collect to new List // pretty print to console using lambda expression System.out.println( "\n\n5. REVERSE sorting of Players by Average :\n" ); sortedByAverage.forEach(playerByRank -> System.out.println(playerByRank)); } } |
Output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | 1 . UNSORTED Players in orginal list : Player [id= 4 , name=Sachin, average= 99.25 , rank= 1 ] Player [id= 1 , name=Dravid, average= 88.55 , rank= 2 ] Player [id= 2 , name=Sehwag, average= 55.65 , rank= 5 ] Player [id= 5 , name=Sourav, average= 66.15 , rank= 4 ] Player [id= 3 , name=Laxman, average= 77.75 , rank= 3 ] 2 . REVERSE sorting of Players by Id : Player [id= 5 , name=Sourav, average= 66.15 , rank= 4 ] Player [id= 4 , name=Sachin, average= 99.25 , rank= 1 ] Player [id= 3 , name=Laxman, average= 77.75 , rank= 3 ] Player [id= 2 , name=Sehwag, average= 55.65 , rank= 5 ] Player [id= 1 , name=Dravid, average= 88.55 , rank= 2 ] 3 . REVERSE sorting of Players by Name : Player [id= 5 , name=Sourav, average= 66.15 , rank= 4 ] Player [id= 2 , name=Sehwag, average= 55.65 , rank= 5 ] Player [id= 4 , name=Sachin, average= 99.25 , rank= 1 ] Player [id= 3 , name=Laxman, average= 77.75 , rank= 3 ] Player [id= 1 , name=Dravid, average= 88.55 , rank= 2 ] 4 . REVERSE sorting of Players by Rank : Player [id= 2 , name=Sehwag, average= 55.65 , rank= 5 ] Player [id= 5 , name=Sourav, average= 66.15 , rank= 4 ] Player [id= 3 , name=Laxman, average= 77.75 , rank= 3 ] Player [id= 1 , name=Dravid, average= 88.55 , rank= 2 ] Player [id= 4 , name=Sachin, average= 99.25 , rank= 1 ] 5 . REVERSE sorting of Players by Average : Player [id= 4 , name=Sachin, average= 99.25 , rank= 1 ] Player [id= 1 , name=Dravid, average= 88.55 , rank= 2 ] Player [id= 3 , name=Laxman, average= 77.75 , rank= 3 ] Player [id= 5 , name=Sourav, average= 66.15 , rank= 4 ] Player [id= 2 , name=Sehwag, average= 55.65 , rank= 5 ] |
References:
- https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html
- https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#StreamOps
- https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html
- https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html
- https://docs.oracle.com/javase/8/docs/api/java/lang/Iterable.html
- https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html
Happy Coding !!
Happy Learning !!