Core Java

Sorting a List having null values with Comparator’s nullsFirst

Hello Friends,

In this tutorial, we will see how we can sort a list of items when few of the items are null in the list using Java 8 Comparator.nullsFirst, such that nulls are treated as smallest elements in the list.

– What is Comparator
– What is nullsFirst method doing in Comparator
– Sorting a list of Strings having non null names
– Sorting a list of Strings having names and Nulls without using nullsFirst
– Solving above problem by sorting the list using nullsFirst method
– Sorting a list of Custom objects without nulls
– Sorting a list of Custom objects with nulls without using nullsFirst
– Solving above problem by sorting the list using nullsFirst method
– Sorting the list having employee with name as null

What is a Comparator? 

Comparator is a FunctionalInterface which has following abstract method

int compare(T 
o1, T 
o2);

So if you want to sort ,say your list.You can create a class implementing Comparator interface’s compare method, wherein you can define the logic of sorting and pass this comparator to the list.sort() method and it will then sort according to your defined logic.

Alternatively, rather than creating a separate class implementing Comparator interface, you can pass lambda function(implementing compare method of Comparator) to list.sort() method.

What is nullsFirst method doing in Comparator?

In Java 8, there has been addition of lots of default and static methods in Comparator interface.

nullsFirst is one of the static method defined in the Comparator interface having following signature :

public
static <T> Comparator<T> nullsFirst(Comparator<?
super T>
comparator)

So what does it do ?

– Returns a null-friendly comparator that considers null to be less than non null.

– When both objects are null, they are considered equal.

– When both are non null, the specified comparator, which is passed to nullsFirst method as parameter, is used to determined the sort order

– When the specified comparator is null, then the returned comparator consider all non null values to be equal.

To understand the usage of nullsFirst , let us try to sort a list of Strings having name of employees ,

–  First without null values  

–  Then with null values but without nullsFirst

–  Then with null values and with nullsFirst 

–  Then we will do same above steps for a custom Employee object  

–   And then we will see what if one of the property on the basis of which sorting needs to be done, is null in a custom object

Sorting a list of Strings having non null names 

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
package com.blogspot.javasolutionsguide;
 
 
import java.util.Arrays;
import java.util.List;
import java.util.Comparator;
 
 
public class ComparatorTestWithListOfNamesWithoutNulls {
 
 public static void main(String[] args) {
 
    List<String> names  = Arrays.asList("Gaurav", "Tendulkar", "Suresh", "Rohit", "Bumrah");
    System.out.println("Before Sorting:");
    names.forEach(System.out ::println);
    names.sort(Comparator.naturalOrder());
    System.out.println("After Sorting:");
    names.forEach(System.out ::println);
 }
1
}

Here is the output :

Before Sorting:

Gaurav

Tendulkar

Suresh

Rohit

Bumrah

After Sorting:

Bumrah

Gaurav

Rohit

Suresh
Tendulkar

Sorting a list of Strings having names and nulls without using nullsFirst

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
package com.blogspot.javasolutionsguide;
 
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
 
 
public class ComparatorTestWithListOfNamesAndNulls {
  public static void main(String[] args) {
     List<String> names  = Arrays.asList("Gaurav", null, "Sachin", "Suresh",null, "Rohit", "Jasprit", null);
     System.out.println("Before Sorting:");
     names.forEach(System.out ::println);
     names.sort(Comparator.naturalOrder());
     System.out.println("After Sorting:");
     names.forEach(System.out ::println);
  }
1
}

Here is the output :

Before Sorting:

Gaurav

null

Sachin

Suresh

null

Rohit

Jasprit

null

Exception in thread “main”
java.lang.NullPointerException

at java.base/java.util.Comparators$NaturalOrderComparator.compare(
Comparators.java:52)

at java.base/java.util.Comparators$NaturalOrderComparator.compare(
Comparators.java:47)

at java.base/java.util.TimSort.countRunAndMakeAscending(
TimSort.java:355)

at java.base/java.util.TimSort.sort(
TimSort.java:220)

at java.base/java.util.Arrays.sort(
Arrays.java:1442)

at java.base/java.util.Arrays$ArrayList.sort(
Arrays.java:4426)

at com.blogspot.javasolutionsguide.ComparatorTestWithListOfNamesAndNulls.main(ComparatorTestWithListOfNamesAndNulls.java:12)

As we can see because ,NaturalOrderComparator’s compare method tries to compare two o objects by invoking compareTo on one of the object, we get NullPointerException.

Solving above problem by sorting the list using nullsFirst method

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
package com.blogspot.javasolutionsguide;
 
import java.util.Arrays;
import java.util.List;
import java.util.Comparator;
 
 
 
/**
 * @author javasolutionsguide
 *
 */
public class ComparatorTestWithNullsFirstForListOfNames {
   public static void main(String[] args) {
       List<String> names  = Arrays.asList("Gaurav", null, "Tendulkar", "Suresh",null, "Rohit", "Jasprit", null);
       System.out.println("Before Sorting:");
       names.forEach(System.out ::println);
       names.sort(Comparator.nullsFirst(Comparator.naturalOrder()));
       System.out.println("After Sorting:");
       names.forEach(System.out ::println);
   }
1
}

Here is the output :

Before Sorting:

Gaurav

null

Tendulkar

Suresh

null

Rohit

Jasprit

null

After Sorting:

null

null

null

Gaurav

Jasprit

Rohit

Suresh

Tendulkar

Sorting a list of custom objects without nulls

We will create an Employee class, which will be a simple POJO as below : 

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
package com.blogspot.javasolutionsguide;
 
 
public class Employee {
 
  private int id;
  private String name;
  private String department;
 
  public Employee(int id, String name, String department) {
    super();
    this.id = id;
    this.name = name;
    this.department = department;
  }
 
  public int getId() {
    return id;
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
}
 
  public String getName() {
    return name;
  }
 
  public String getDepartment() {
   return department;
  }
 
  @Override
  public String toString() {
   return "Employee [id=" + id + ", name=" + name + ", department=" + department + "]";
  }
}

And here is our test class :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
package com.blogspot.javasolutionsguide;
 
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
 
 
public class ComparatorTestWithListOfEmployeesWithoutNulls {
  public static void main(String[] args) {
      List<Employee> employees = Arrays.asList(new Employee(1, "Gaurav", "IT"),
      new Employee(1, "Tendulkar", "Admin"),
      new Employee(1, "Suresh", "IT"),
      new Employee(1, "Rohit", "Admin"),
      new Employee(1, "Bumrah", "Admin"));
      System.out.println("Before Sorting:");
      employees.forEach(System.out ::println);
      System.out.println("After Sorting:");
      employees.sort(Comparator.comparing(Employee :: getName));
      employees.forEach(System.out::println);
1
}

Here is the output :

Before Sorting:

Employee [id=1, name=Gaurav, department=IT]

Employee [id=1, name=Tendulkar, department=Admin]

Employee [id=1, name=Suresh, department=IT]

Employee [id=1, name=Rohit, department=Admin]

Employee [id=1, name=Bumrah, department=Admin]

After Sorting:

Employee [id=1, name=Bumrah, department=Admin]

Employee [id=1, name=Gaurav, department=IT]

Employee [id=1, name=Rohit, department=Admin]

Employee [id=1, name=Suresh, department=IT]

Employee [id=1, name=Tendulkar, department=Admin]

Sorting a list of custom objects with nulls without using nullsFirst

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
package com.blogspot.javasolutionsguide;
 
 
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
 
 
public class ComparatorTestWithListOfEmployeesWithNulls {
 
  public static void main(String[] args) {
  
   List<Employee> employees = Arrays.asList(new Employee(1, "Gaurav", "IT"),
   null,
   new Employee(1, "Tendulkar", "Admin"),
   new Employee(1, "Suresh", "IT"),
1
2
3
4
5
6
7
null,
   new Employee(1, "Rohit", "Admin"),
   new Employee(1, "Bumrah", "Admin"),
   null);
 
   employees.sort(Comparator.comparing(Employee::getName));
   employees.forEach(System.out::println);
1
}
1
}

Here is the output :

Before Sorting:

Employee [id=1, name=Gaurav, department=IT]

null

Employee [id=1, name=Tendulkar, department=Admin]

Employee [id=1, name=Suresh, department=IT]

null

Employee [id=1, name=Rohit, department=Admin]

Employee [id=1, name=Bumrah, department=Admin]

null

Exception in thread “main”
java.lang.NullPointerException

at java.base/java.util.Comparator.lambda$comparing$77a9974f$1(
Comparator.java:469)

at java.base/java.util.TimSort.countRunAndMakeAscending(
TimSort.java:355)

at java.base/java.util.TimSort.sort(
TimSort.java:220)

at java.base/java.util.Arrays.sort(
Arrays.java:1442)

at java.base/java.util.Arrays$ArrayList.sort(
Arrays.java:4426)

at com.blogspot.javasolutionsguide.ComparatorTestWithListOfEmployeesWithNulls.main(ComparatorTestWithListOfEmployeesWithNulls.java:19)

Solving above problem by sorting the list using nullsFirst method 

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
package com.blogspot.javasolutionsguide;
 
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
 
 
public class ComparatorTestWithListOfEmployeesWithNullsAndNullsFirst {
 
  public static void main(String[] args) {
 
     List<Employee> employees = Arrays.asList(new Employee(1, "Gaurav", "IT"),
     null,
     new Employee(1, "Tendulkar", "Admin"),
     new Employee(1, "Suresh", "IT"),
1
2
3
4
5
6
7
8
null,
     new Employee(1, "Rohit", "Admin"),
     new Employee(1, "Bumrah", "Admin"),
     null);
     Collections.sort(employees ,Comparator.nullsFirst((emp1 ,emp2) -> emp1.getName().compareToIgnoreCase(emp2.getName())));
     employees.forEach(System.out::println);
  }
}

Here is the output :

null

null

null

Employee [id=1, name=Bumrah, department=Admin]

Employee [id=1, name=Gaurav, department=IT]

Employee [id=1, name=Rohit, department=Admin]

Employee [id=1, name=Suresh, department=IT]

Employee [id=1, name=Tendulkar, department=Admin]

Sorting the list having employee with name as null

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.blogspot.javasolutionsguide;
 
 
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
 
 
public class ComparatorTestWithListOfEmployeesWithNullNamesAndNullsFirst {
 
  public static void main(String[] args) {
     List<Employee> employees = Arrays.asList(new Employee(1, "Gaurav", "IT"),
     new Employee(1, "Tendulkar", "Admin"),
     new Employee(1, null, "IT"),
     new Employee(1, "Rohit", "Admin"),
     new Employee(1, "Bumrah", "Admin"));
     System.out.println("Before Sorting:");
     employees.forEach(System.out ::println);
     employees.sort(Comparator.comparing(Employee::getName,Comparator.nullsFirst(Comparator.naturalOrder())));
     System.out.println("After Sorting:");
     employees.forEach(System.out::println);
  }
}

Here is the output :

Before Sorting:

Employee [id=1, name=Gaurav, department=IT]

Employee [id=1, name=Tendulkar, department=Admin]

Employee [id=1, name=null, department=IT]

Employee [id=1, name=Rohit, department=Admin]

Employee [id=1, name=Bumrah, department=Admin]

After Sorting:

Employee [id=1, name=null, department=IT]

Employee [id=1, name=Bumrah, department=Admin]

Employee [id=1, name=Gaurav, department=IT]

Employee [id=1, name=Rohit, department=Admin]

Employee [id=1, name=Tendulkar, department=Admin]

Summary

When we have  list of elements where few elements are null and we want these nulls to be treated as the smallest elements in the list, we can use nullsFirst method of Comparator interface, which does following :

Returns a null-friendly comparator that considers null to be less than non null.

– When both objects are null, they are considered equal.

– When both are non null, the specified comparator, which is passed to nullsFirst method as parameter, is used to determined the sort order

– When the specified comparator is null, then the returned comparator consider all non null values to be equal.

Thanks for reading. If you liked the post, you can share it and can subscribe to this blog for more such posts.

Published on Java Code Geeks with permission by Gaurav Bhardwaj, partner at our JCG program. See the original article here: Sorting a List having null values with Comparator’s nullsFirst

Opinions expressed by Java Code Geeks contributors are their own.

Gaurav Bhardwaj

Gaurav has done Masters in Computer Applications(MCA) and is working in Software development field for more than 10 years in Java/J2EE technologies. He is currently working with one of top MNC. He has worked on various frameworks like Struts, Spring, Spring Boot, Angular JS, JSF, Velocity, iBatis, MyBatis, Hibernate, JUnit, Mockito, Dozzer. He likes to explore new technologies and share his thoughts by writing a technical blog. He is the founder of JavaSolutionsGuide.blogspot.com.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button