ppb
ppb

Reputation: 2613

Java list null check before Stream and return as Optional

I am getting list of objects from API

public Optional<List<Employee>> getEmployeeData (String deptId){

     List<Employee> employee = departmentClient.employeeData(deptId);

     //Based on some condition I am filtering employee list but before that I want to check  for null for list.

    return Optional.ofNullable(employee).orElse(Collections.emptyList())
            .stream()
            .filter(Objects::nonNull)
            .filter(e -> e.getType != null)
            .collect(Collectors.toList());

 }

But I think as method return type is Optional<> this is giving error. How can I check null for the List before the Stream and return as an Optional<List<..>>

Upvotes: 0

Views: 9463

Answers (3)

Mafor
Mafor

Reputation: 10681

And yet another option:

return Optional.ofNullable(employee)
        .map(list -> list.stream()
                .filter(Objects::nonNull)
                .filter(e -> e.getType() != null)
                .collect(Collectors.toList()));

The lambda inside .map(...) is executed only if the emploee list is not null, otherwise an empty Optional is returned.

Upvotes: 2

Nikolas
Nikolas

Reputation: 44378

Your solution doesn't work because the result of Optional is List and you collect it through the Stream pipelines back to the List.

Using Java 8 you can wrap all your solution inside Optional or better use the advantage of the Collectors instead:

Optional<List<Employee>> o = Optional
        .ofNullable(employees)                  // employees can be null, right?
        .orElse(Collections.emptyList())        // ... if so, then empty List
        .stream()                               // Stream<Employee>
        .filter(Objects::nonNull)               // Stream<Employee> filtered as non-nulls
        .filter(e -> e.getType() != null)       // Stream<Employee> with non-null field
        .collect(Collectors.collectingAndThen(  
            Collectors.toList(),                // Collected to List<Employee>
            Optional::of));                     // Collected to Optional<List<Employee>>

The Collectors::collectingAndThen(Collector<T,A,R> downstream, Function<R,RR> finisher) method behaves as usual Collector providing a subsequent mapping function taking the collected result. In our case, we simply wrap the List into Optional to be returned.

  • Collector downstream collects to List<Employee>
  • Function finisher maps List<Employee> to Optional<List<Employee>>

With Java 9 and higher using Optional::stream, the beginning might be little different:

Optional<List<Employee>> o = Optional
        .ofNullable(employees)                  // null-safe employees
        .stream()                               // Stream<List<Employees>>
        .flatMap(List::stream)                  // Stream<Employees>
        .filter(Objects::nonNull) 
        ......

Upvotes: 2

Hadi
Hadi

Reputation: 17289

You returned List<Employee> while your method signature is Optional<List<Employee>>

Try this one:

return employee != null ? Optional.of(employee.stream()
            .filter(Objects::nonNull)
            .filter(e -> e.getType != null)
            .collect(Collectors.toList())) : Optional.ofNullable(Collections.emptyList());

Upvotes: 3

Related Questions