karvai
karvai

Reputation: 1767

Perform a filter within a function call

Is there a way I could perform a filter within the steps of the following function call?

The following works fine but I wish to add a null/empty check on getResults which returns a list of Results object.

I could try to .stream() on it like getResults().stream().filter();

But kind of pointless since getResults().stream() could potentially throw a null pointer already.
Also this returns a stream of Result. But I want to do a check on the List of Result itself, like:

.filter(CollectionUtils::isNotEmpty)

Is there a way to do this?

public MyFunc(Helper helper) {

    Function<String, HttpEntity<Request>> createRequestFunction = helper::createRequest;

    this.fetch = createRequestFunction
            .andThen(helper::getResponse)
            .andThen(Response::getQuery)
            .andThen(QueryResult::getResults)
            
            // I want to make a filter here .filter(CollectionUtils::isNotEmpty) to ensure
            // getResults (It is a List<Result> type) is not null or empty 

            .andThen(results -> results.stream()
                    .map(Result::getKey)
                    .filter(StringUtils::isNotBlank)
                    .map(s -> s.split("\\|"))
                    .filter(data -> data.length == 2)
                    .map(data -> data[1])
                    .collect(Collectors.toList()));
}

Upvotes: 1

Views: 81

Answers (1)

Anton Balaniuc
Anton Balaniuc

Reputation: 11739

createRequestFunction has type of Function<String, HttpEntity<Request>>

Function itself doesn't have a filter operation. It is possible to either append additional function via andThen or prepend via compose.

What is expected behaviour if QueryResult::getResults is null? What is the value of this.fetch should be?

One possible option is to wrap result of QueryResult::getResults into an Optional. Something similar to this:

this.fetch = createRequestFunction
            .andThen(helper::getResponse)
            .andThen(Response::getQuery)
            .andThen(QueryResult::getResults)
            .andThen(Optinal::ofNullable); 

so the result of this.fetch is Optinal<List<Result>> and it is possible to execut different logic based on the fact if optional is empty or not.

e.g

return 
  this.fetch // Optinal<List<Result>>
  .getOrElse(Collections.emptyList()) // value of optional if it is not empty, or empty list otherwise 
  .stream()
                    .map(Result::getKey)
                    .filter(StringUtils::isNotBlank)
                    .map(s -> s.split("\\|"))
                    .filter(data -> data.length == 2)
                    .map(data -> data[1])
                    .collect(Collectors.toList())

Upvotes: 1

Related Questions