In this article, we will see how to sort list and Array of objects with null values present
Generally, sorting any List/Array which contains one/more null values in it, results in throwing NullPointerException when comparing null value with other values
To resolve this NullPointerException, either we have to handle null values inside the Comparator logic (before Java 8 approach) or use static methods nullsFirst() & nullsLast() of Comparator interface introduced in Java 8
Sorting List and Arrays with null values :
Let’s discuss this topic under different sub-topics as listed below,
- Throws NullPointerException when sorting list with null values
- Before Java 8 – Manually handle null values while sorting
- Java 8 – Sorting List of Integers with null values
- Java 8 – Sorting List of String with null values
- Java 8 – Sorting List of Customer objects with null values
- Java 8 – Filter out null values and Sort String elements
- Collections.sort() method
- Arrays.sort() method
1. Throws NullPointerException when sorting list with null values :
- Here, we are trying to sort list of String elements which contains null values
- In the below example, while comparing null values Comparator throws NullPointerException
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 | package net.bench.resources.stream.sorting.nullvalues; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; public class SortingNullValuesThrowsNPE { public static void main(String[] args) { // 1. string list List<String> names = Arrays.asList( null , "Kimi" , "Michael" , null , "Alonso" , "Narain" , null ); // 2.1 Sorting list with null values Collections.sort(names, Comparator.naturalOrder()); } } |
Output:
1 2 3 4 5 6 7 8 9 10 11 12 | Exception in thread "main" java.lang.NullPointerException at java.lang.String.compareTo(String.java: 1155 ) at java.lang.String.compareTo(String.java: 111 ) at java.util.Comparators$NaturalOrderComparator.compare(Comparators.java: 52 ) at java.util.Comparators$NaturalOrderComparator.compare(Comparators.java: 47 ) at java.util.TimSort.countRunAndMakeAscending(TimSort.java: 355 ) at java.util.TimSort.sort(TimSort.java: 220 ) at java.util.Arrays.sort(Arrays.java: 1438 ) at java.util.Arrays$ArrayList.sort(Arrays.java: 3895 ) at java.util.Collections.sort(Collections.java: 175 ) at net.bench.resources.stream.sorting.nullvalues.SortingNullValuesThrowsNPE .main(SortingNullValuesThrowsNPE.java: 24 ) |
2. Before Java 8 – Manually handle null values while sorting :
- To get rid of the NullPointerException we encountered in the previous example, we are going handle null values manually inside Comparator logic by pushing them to last
- But still we have to make our hands dirty by writing/coding/developing logic inside Comparator to push null values to either first/last position
- A more elegant way is to use static methods (nullsFirst & nullsLast) introduced in the Java 8’s Comparator interface, which we will see in the following examples no. 3
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.sorting.nullvalues; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; public class SortingBeforeJava8Approach { public static void main(String[] args) { // 1. string list List<String> names = Arrays.asList( null , "Kimi" , "Michael" , null , "Alonso" , "Narain" , null ); // 1.1 printing original names list System.out.println( "Unsorted names list with NULL values :- \n" ); names.forEach(System.out::println); // 2. System.out.println( "\n\nCollections.sort() with NULL values Last:- \n" ); // 2.1 Sorting using Collections.sort() with null values last Collections.sort(names, new Comparator<String>() { @Override public int compare(String str1, String str2) { if ( null == str1) { return null == str2 ? 0 : 1 ; } else if ( null == str2) { return - 1 ; } return str1.compareTo(str2); } }); // 2.2 print to console names.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 | Unsorted names list with NULL values :- null Kimi Michael null Alonso Narain null Collections.sort() with NULL values Last:- Alonso Kimi Michael Narain null null null |
3. Java 8 – Sorting List of Integers with null values :
- Here, we are sorting list of integers which contains null values using static methods nullsFirst() & nullsLast() of Comparator interface
- Comparator.nullsFirst() – this comparator helps to push null values to first/starting position
- Comparator.nullsLast() – this comparator helps to push null values to last/ending position
- Rest of the non-null integer values will be sorted either in ascending/descending order according to the Comparator passed as argument to static methods i.e.; nullsFirst() & nullsLast()
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 | package net.bench.resources.stream.sorting.nullvalues; import java.util.Arrays; import java.util.Comparator; import java.util.List; public class IntegerSortingUsingJava8 { public static void main(String[] args) { // integer list List<Integer> names = Arrays.asList( 97 , null , 63 , 19 , null , 86 , 23 , null ); // printing original number list System.out.println( "Unsorted number list with NULL values :- \n" ); names.forEach(System.out::println); // stream sorting with null values first System.out.println( "\n\nSorted number list with NULL values First:- \n" ); names .stream() .sorted(Comparator.nullsFirst(Comparator.naturalOrder())) .forEach(System.out::println); // stream sorting with null values last System.out.println( "\n\nSorted number list with NULL values Last:- \n" ); names .stream() .sorted(Comparator.nullsLast(Comparator.naturalOrder())) .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 24 25 26 27 28 29 30 31 32 33 34 | Unsorted number list with NULL values :- 97 null 63 19 null 86 23 null Sorted number list with NULL values First:- null null null 19 23 63 86 97 Sorted number list with NULL values Last:- 19 23 63 86 97 null null null |
4. Java 8 – Sorting List of String with null values :
- Here, we are sorting list of String elements which contains null values using static methods nullsFirst() & nullsLast() of Comparator interface
- Comparator.nullsFirst() – this comparator helps to push null values to first/starting position and for sorting rest of the non-null String elements we can pass either Comparator.naturalOrder() or Comparator.reverseOrder() to get result in natural/reverse order respectively
- Comparator.nullsLast() – this comparator helps to push null values to last/ending position and similarly rest of the non-null items can be sorted
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 | package net.bench.resources.stream.sorting.nullvalues; import java.util.Arrays; import java.util.Comparator; import java.util.List; public class StringSortingUsingJava8 { public static void main(String[] args) { // string list List<String> names = Arrays.asList( null , "Kimi" , "Michael" , null , "Alonso" , "Narain" , null ); // printing original names list System.out.println( "Unsorted names list with NULL values :- \n" ); names.forEach(System.out::println); // stream sorting with null values first System.out.println( "\n\nSorted names list with NULL values First:- \n" ); names .stream() .sorted(Comparator.nullsFirst(Comparator.naturalOrder())) .forEach(System.out::println); // stream sorting with null values last System.out.println( "\n\nSorted names list with NULL values Last:- \n" ); names .stream() .sorted(Comparator.nullsLast(Comparator.naturalOrder())) .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 24 25 26 27 28 29 30 31 | Unsorted names list with NULL values :- null Kimi Michael null Alonso Narain null Sorted names list with NULL values First:- null null null Alonso Kimi Michael Narain Sorted names list with NULL values Last:- Alonso Kimi Michael Narain null null null |
5. Java 8 – Sorting List of Customer objects with null values :
- We are going to sort list of Customer objects which contains null values according to their name in alphabetical order
- Comparator.nullsFirst() – this comparator helps to push null values to first/starting position and to sort rest of the non-null Customer objects according to their name we can pass either Lambda Expression or Method Reference to Stream‘s sorted() method
- Comparator.nullsLast() – this comparator helps to push null values to last/ending position and similarly to sort rest of the non-null Customer objects according to their name we can pass either Lambda Expression or Method Reference to Stream‘s sorted() method
Customer.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | package net.bench.resources.stream.sorting.nullvalues; public class Customer { // member variables String custName; String custCity; Integer custAge; // 3-arg parameterized constructor // getters & setters // toString() method } |
CustomerSortingUsingJava8.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 | package net.bench.resources.stream.sorting.nullvalues; import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; public class CustomerSortingUsingJava8 { // customer list private static List<Customer> getUnSortedCustomers() { return Arrays.asList( null , new Customer( "Sneha" , "Pune" , 73 ), new Customer( "Simran" , "Bangalore" , 37 ), new Customer( "Nayanthara" , "Hyderabad" , 52 ), new Customer( "Shalini" , "Chennai" , 70 ), null , new Customer( "Abirami" , "Bangalore" , 48 ), new Customer( "Trisha" , "Mangalore" , 45 ), null ); } public static void main(String[] args) { // get customer list List<Customer> unsortedCustomerList = getUnSortedCustomers(); System.out.println( "Before Sorting: Customer list :- \n" ); unsortedCustomerList.stream().forEach(System.out::println); System.out.println( "\n\nSorted Customer list on Name" + " with NULL values First :- \n" ); // inline - sorting on multiple fields List<Customer> sortedCustomerListWithNullFirst = unsortedCustomerList .stream() .sorted(Comparator.nullsFirst(Comparator .comparing(Customer::getCustName))) .collect(Collectors.toList()); // collect sorted customers to new list // print new list to console using forEach() sortedCustomerListWithNullFirst.stream().forEach(System.out::println); System.out.println( "\n\nSorted Customer list on Name" + " with NULL values Last :- \n" ); // inline - sorting on multiple fields List<Customer> sortedCustomerListWithNullLast = unsortedCustomerList .stream() .sorted(Comparator.nullsLast(Comparator .comparing(Customer::getCustName))) .collect(Collectors.toList()); // collect sorted customers to new list // print new list to console using forEach() sortedCustomerListWithNullLast.stream().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 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | Before Sorting: Customer list :- null Customer [custName=Sneha, custCity=Pune, custAge= 73 ] Customer [custName=Simran, custCity=Bangalore, custAge= 37 ] Customer [custName=Nayanthara, custCity=Hyderabad, custAge= 52 ] Customer [custName=Shalini, custCity=Chennai, custAge= 70 ] null Customer [custName=Abirami, custCity=Bangalore, custAge= 48 ] Customer [custName=Trisha, custCity=Mangalore, custAge= 45 ] null Sorted Customer list on Name with NULL values First :- null null null Customer [custName=Abirami, custCity=Bangalore, custAge= 48 ] Customer [custName=Nayanthara, custCity=Hyderabad, custAge= 52 ] Customer [custName=Shalini, custCity=Chennai, custAge= 70 ] Customer [custName=Simran, custCity=Bangalore, custAge= 37 ] Customer [custName=Sneha, custCity=Pune, custAge= 73 ] Customer [custName=Trisha, custCity=Mangalore, custAge= 45 ] Sorted Customer list on Name with NULL values Last :- Customer [custName=Abirami, custCity=Bangalore, custAge= 48 ] Customer [custName=Nayanthara, custCity=Hyderabad, custAge= 52 ] Customer [custName=Shalini, custCity=Chennai, custAge= 70 ] Customer [custName=Simran, custCity=Bangalore, custAge= 37 ] Customer [custName=Sneha, custCity=Pune, custAge= 73 ] Customer [custName=Trisha, custCity=Mangalore, custAge= 45 ] null null null |
6. Java 8 – Filter out null values and Sort String elements :
- First remove null values from list of Strings using Stream‘s filter() method
- After filtering out null values from the list, we can sort rest of the String elements present in the list by passing Comparator to Stream‘s sorted() method
- Use Comparator.naturalOrder() method for ascending order (or alphabetical order)
- Use Comparator.reverseOrder() method for sorting String elements in reverse alphabetical order
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 | package net.bench.resources.stream.sorting.nullvalues; import java.util.Arrays; import java.util.Comparator; import java.util.List; public class FilterAndThenSortUsingJava8 { public static void main(String[] args) { // string list List<String> names = Arrays.asList( null , "Kimi" , "Michael" , null , "Alonso" , "Narain" , null ); // printing original names list System.out.println( "Unsorted names list with NULL values :- \n" ); names.forEach(System.out::println); // remove null values using filter() and then sorted() System.out.println( "\n\nSorted names list " + "after filtering out NULL values :- \n" ); names // original data source .stream() // sequential stream .filter(str -> null != str) // filter() .sorted(Comparator.naturalOrder()) //sorted() .forEach(System.out::println); // forEach() } } |
Output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | Unsorted names list with NULL values :- null Kimi Michael null Alonso Narain null Sorted names list after filtering out NULL values :- Alonso Kimi Michael Narain |
7. Collections.sort() method :
- This method takes 2 arguments viz.; first is actual list to be sorted and 2nd is the Comparator
- Since we are trying to sort the list with null values present, therefore we can use either nullsFirst() or nullsLast() static methods to push null values to starting/ending position respectively
- Additionally, we have to pass another Comparator as argument to nullFirst/nullsLast static methods for sorting rest of the non-null values in either ascending/descending order
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 | package net.bench.resources.stream.sorting.nullvalues; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; public class Java8SortingUsingCollectionsSortMethod { public static void main(String[] args) { // 1. string list List<String> names = Arrays.asList( null , "Kimi" , "Michael" , null , "Alonso" , "Narain" , null ); // 1.1 printing original names list System.out.println( "Unsorted names list with NULL values :- \n" ); names.forEach(System.out::println); // 2.1 Sorting using Collections.sort() with null values first Collections.sort(names, Comparator .nullsFirst(Comparator.naturalOrder())); // 2.2 nullsFirst -> print to console System.out.println( "\n\nCollections.sort() with NULL values First:- \n" ); names.forEach(System.out::println); // 3.1 Sorting using Collections.sort() with null values first Collections.sort(names, Comparator .nullsLast(Comparator.naturalOrder())); // 3.2 nullsLast -> print to console System.out.println( "\n\nCollections.sort() with NULL values Last:- \n" ); names.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 24 25 26 27 28 29 30 31 | Unsorted names list with NULL values :- null Kimi Michael null Alonso Narain null Collections.sort() with NULL values First:- null null null Alonso Kimi Michael Narain Collections.sort() with NULL values Last:- Alonso Kimi Michael Narain null null null |
8. Arrays.sort() method :
- This is also very similar to Collections.sort() method except that 1st argument is array
- This method takes 2 arguments viz.; first is actual array to be sorted and 2nd is the Comparator
- Since we are trying to sort the array with null values present, therefore we can use either nullsFirst() or nullsLast() static methods to push null values to starting/last position respectively
- Additionally, we have to pass another Comparator as argument to nullFirst/nullsLast methods for sorting rest of the non-null values in either ascending/descending order
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 | package net.bench.resources.stream.sorting.nullvalues; import java.util.Arrays; import java.util.Comparator; public class Java8SortingUsingArraysSortMethod { public static void main(String[] args) { // 1. string list String[] names = { null , "Kimi" , "Michael" , null , "Alonso" , "Narain" , null }; // 1.1 printing original names list System.out.println( "Unsorted names list with NULL values :- \n" ); System.out.println(Arrays.toString(names)); // 2.1 Sorting using Arrays.sort() with null values first Arrays.sort(names, Comparator.nullsFirst(Comparator.naturalOrder())); // 2.2 nullsFirst -> print to console System.out.println( "\n\nArrays.sort() with NULL values First:- \n" ); System.out.println(Arrays.toString(names)); // 3.1 Sorting using Arrays.sort() with null values first Arrays.sort(names, Comparator.nullsLast(Comparator.naturalOrder())); // 3.2 nullsLast -> print to console System.out.println( "\n\nArrays.sort() with NULL values Last:- \n" ); System.out.println(Arrays.toString(names)); } } |
Output:
1 2 3 4 5 6 7 8 9 10 11 12 13 | Unsorted names list with NULL values :- [ null , Kimi, Michael, null , Alonso, Narain, null ] Arrays.sort() with NULL values First:- [ null , null , null , Alonso, Kimi, Michael, Narain] Arrays.sort() with NULL values Last:- [Alonso, Kimi, Michael, Narain, null , null , null ] |
Related Articles:
- Java 8 – How to sort ArrayList elements
- Java 8 – Sorting List of primitive, String & Custom Objects
- Java 8 – Sorting ArrayList using sort() method of List
- Java 8 – How to sort LinkedList elements
- Java 8 – How to sort HashSet elements
- Java 8 – How to sort LinkedHashSet elements
- Java 8 – How to sort TreeSet in descending order
- Java 8 – How to sort List and Arrays with null values present
- Java 8 – How to sort Arrays in Ascending and Descending order ?
- Java 8 – Sorting list of objects on multiple fields (3-level attributes)
References:
- https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html
- https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html
- https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html
- https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html
Happy Coding !!
Happy Learning !!