Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle nullable lists using java 8?

I'm making a service call and trying to handle response. Response might have a list of something. That list might be null.

Moreover, if list not null or not empty, then it needs to be filtered. In the code "entry" reference might be null if filtering gives nothing or response list is empty or null.

Currently i'm getting NPE when i try to use stream() on a null response list. How can i handle this situation?

@Getter
public class ServiceResponse {  
    List<ResponseEntry> entryList;
}

@Getter
public class ResponseEntry {
    String value;
}


ServiceResponse serviceResponse = service.getServiceResponse();
ResponseEntry entry = serviceResponse.getEntryList()
    .stream()
    .filter(e -> "expectedValue".equals(e.getValue()))
    .findFirst()
    .orElse(null);

if (entry == null) { ... }

like image 782
Kyle Bak Avatar asked Dec 26 '18 23:12

Kyle Bak


People also ask

How do you handle null values in Java 8?

With the release of Java 8, a straight-forward way of handling null references was provided in the form of a new class: java. util. Optional<T> . It's a thin wrapper around other objects, so you can interact fluently with the Optional instead of a null reference directly if the contained object is not present.

How do I avoid multiple nulls in Java 8?

We can get rid of all those null checks by utilizing the Java 8 Optional type. The method map accepts a lambda expression of type Function and automatically wraps each function result into an Optional . That enables us to pipe multiple map operations in a row. Null checks are automatically handled under the hood.


1 Answers

if list not null or not empty, then it needs to be filtered.

No need for Optional here, as it's not intended to replace simple if checks.

ResponseEntry entry = null;
List<ResponseEntry> responseEntries = serviceResponse.getEntryList();
if(responseEntries != null && !responseEntries.isEmpty()){
    entry = responseEntries.stream()
                .filter(e -> "expectedValue".equals(e.getValue()))
                .findFirst()
                .orElse(null);
}
  • reads "if responseEntries is not null and responseEntries is not empty then apply the filter operation and find the first item or else null". Very readable.

On the other hand, the optional approach:

ResponseEntry entry = Optional.ofNullable(serviceResponse.getEntryList())
                              .orElseGet(() -> Collections.emptyList())
                              .stream()
                              .filter(e -> "expectedValue".equals(e.getValue()))
                              .findFirst();

if(!entry.isPresent()){ ... } // or entry.ifPresent(e -> ...) depending on the logic you're performing inside the block
  • unnecessarily creates objects that could be avoided and not really the intention of optional to be used as a substitute for simple "if" checks.
like image 119
Ousmane D. Avatar answered Sep 19 '22 19:09

Ousmane D.