nimo23
nimo23

Reputation: 5680

java stream with optional filter predicate

Is this (version 1):

   public List<Task> getTasks(Set<Task> tasks, Predicate<? super Task> predicate) {
    var stream = tasks.stream();
    if (predicate != null) stream.filter(predicate);
    // is the stream filtered if predicate != null ?
    return stream.collect(Collectors.toList());
}

the same as this (version 2):

   public List<Task> getTasks(Set<Task> tasks, Predicate<? super Task> predicate) {
    var stream = tasks.stream();
    // do I must reassign the stream to have the filtering
    if (predicate != null) stream = stream.filter(predicate);
    return stream.collect(Collectors.toList());
}

EDIT:

Only version 2 is correct, version 1 is incorrect.

Related question:

Is there a way to bypass an itermediate operation without using the solution of version 2? For example,

stream.filter(pred == null ? Void : predicate)
      .order(comparator == null ? Void : comparator);

Upvotes: 1

Views: 1026

Answers (2)

Naman
Naman

Reputation: 31888

Answer by @Jason is to the point. While the first code block does not filter out anything since you do not update the existing stream, the second selectively returns the tasks based on a non-null predicate.

To complete the answer, you can simplify the code to

public List<Task> getTaskss(Set<Task> tasks, Predicate<? super Task> predicate) {
    return predicate == null ? new ArrayList<>(tasks) :
            tasks.stream().filter(predicate).collect(Collectors.toList());
}

Upvotes: 1

Jason
Jason

Reputation: 5246

No they are not the same. You have to do the re-assignment to Stream because filter doesn't mutate the underlying stream it creates a new Stream object. Very good question though.

Upvotes: 4

Related Questions