Java 8 – How to sort List and Arrays with null values

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

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
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:

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
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:

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()
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:

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
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:

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

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

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:

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
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:

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
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:

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
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:

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]

References:

Happy Coding !!
Happy Learning !!

Java 8 - Sorting list of objects on multiple fields
Java 8 – How to sort TreeSet in descending order using Stream