In Java 8, is there a way to apply the filter on a stream based on a condition,
example
I have this stream
if (isAccessDisplayEnabled) {
src = (List < Source > ) sourceMeta.getAllSources.parallelStream()
.filter(k - > isAccessDisplayEnabled((Source) k))
.filter(k - > containsAll((Source) k, substrings, searchString))
.collect(Collectors.toList());
} else {
src = (List < Source > ) sourceMeta.getAllSources.parallelStream()
.filter(k - > containsAll((Source) k, substrings, searchString))
.collect(Collectors.toList());
}
I am adding the filter
.filter(k - > isAccessDisplayEnabled((Source) k)))
on the stream based on the if-else condition. Is there a way to avoid that if-else, since if there are more filters coming up,then it will be hard to maintain.
Please let me know
One way to do it is
Stream<Source> stream = sourceMeta.getAllSources.parallelStream().map(x -> (Source)x);
if(isAccessDisplayEnabled) stream = stream.filter(s -> isAccessDisplayEnabled(s));
src = stream.filter(s - > containsAll(s, substrings, searchString))
.collect(Collectors.toList());
another
src = sourceMeta.getAllSources.parallelStream().map(x -> (Source)x)
.filter(isAccessDisplayEnabled? s - > isAccessDisplayEnabled(s): s -> true)
.filter(s - > containsAll(s, substrings, searchString))
.collect(Collectors.toList());
In either case, note how performing one type cast at the beginning simplifies the entire stream pipline.
Both solutions avoid re-evaluating isAccessDisplayEnabled
for every stream element, however, the second relies on the JVM’s capability of inlining s -> true
when this code turns out to be performance critical.
Your condition has the same name as your method. I'm going to assume you meant for those to be different, so let's say it was this:
if (someCondition) {
src = (List < Source > ) sourceMeta.getAllSources.parallelStream()
.filter(k - > isAccessDisplayEnabled((Source) k))
.filter(k - > containsAll((Source) k, substrings, searchString))
.collect(Collectors.toList());
} else {
src = (List < Source > ) sourceMeta.getAllSources.parallelStream()
.filter(k - > containsAll((Source) k, substrings, searchString))
.collect(Collectors.toList());
}
If you want to remove the if/else, you can instead perform the check in the first filter:
src = (List < Source > ) sourceMeta.getAllSources.parallelStream()
.filter(k - > !someCondition || isAccessDisplayEnabled((Source) k))
.filter(k - > containsAll((Source) k, substrings, searchString))
.collect(Collectors.toList());
In the else case, you take everything and remove the isAccessDisplayEnabled() method call, so the condition is effectively "if someCondition is false or isAccessDisplayEnabled(k)". If someCondition comes out false, then the isAccessDisplayEnabled() check is skipped.