How to return a nullable List from an object that can be null with streams

829 Views Asked by At

I have a method that takes an object having an ArrayList inside:

private List<String> getWatchlistDetail(MatchData k) {
        if(k == null)
            return new ArrayList<>();
        return
                k.getWatchListDetail()
                        .stream()
                        .collect(Collectors.toList());
    }

MatchData k can be null, and sometimes k.getWatchListDetail() also could be null.

I need to check both condition. First, if it can throw NPE.

Above implementation does it, but I am trying to use perhaps Optional.ofNullable() or streams with chaining, so I can do it in one line of chaining.

1

There are 1 best solutions below

4
On

MatchData k is null, sometimes k.getWatchListDetail() is also null so I need to check both

... so I can do it in one line of chaining.

Sure, you can check both in a single stream statement.

private List<String> getWatchlistDetail(MatchData k) {
    
    return Stream.ofNullable(k)
        .map(MatchData::getWatchListDetail)
        .filter(Objects::nonNull)
        .flatMap(List::stream)
        .collect(Collectors.toList());
}

But, keep in mind:

  • It's not a remedy, but an attempt to hide a design flaw.
  • It has a cost of generating a new completely identical collection. Which is not good at all.

Now compare it with the method below, which neither hides null-checks, no abuses streams and optional:

private List<String> getWatchlistDetail(MatchData k) {
    
    return k != null && k.getWatchListDetail() != null ?
           k.getWatchListDetail() : Collections.emptyList();
}

Functional programming was introduced in Java to reduce complexity of code, not the opposite, using it only for the purpose of hiding null-checks would not bay you anything.

By itself, null-check are not a problem, but only an indicator of a problem. And to address it, need to refine the design of your application.

use perhaps Optional.ofNullable

In regard to the question whether it's possible to utilize optional in order to avoid conditional logic, take a look at this answer by @StuartMarks (JDK developer):

The primary use of Optional is as follows:

Optional is intended to provide a limited mechanism for library method return types where there is a clear need to represent "no result," and where using null for that is overwhelmingly likely to cause errors.

A typical code smell is, instead of the code using method chaining to handle an Optional returned from some method, it creates an Optional from something that's nullable, in order to chain methods and avoid conditionals.