'What is the Java Stream way to use a different filtering (if any) on a collection, based on external conditions?
What is the Java Stream way to use different filtering (if any) on a collection, based on external conditions?
For example, I have an initial collection of elements:
List<Data> initialData = ...
And I want to filter them, in case of some additional external boolean condition:
List<Data> data = something.isTrue() ? initialData.stream().filter() : initialData;
Solution 1:[1]
More of an addendum: keep in mind that using streams comes with a certain overhead. Yes, using it leads to nice, concise code (when you know what are doing), but there is runtime cost for establishing streams. From that point of view, it isn't necessarily always the "best" option to do things inside the stream.
Meaning: the given example isn't just about style. There might be a significant performance penalty for turning the external check into something that always streams your collection.
Solution 2:[2]
A function that filters a list. As parameters the list, the field function, the comparison function and the comparison value.
What does such a function look like:
public <T, S> List<S> myFilter(List<S> from, Function<S, T> where, BiPredicate<T, T> predicate, T by) {
return from.stream().filter(f -> predicate.test(where.apply(f), by)).collect(Collectors.toList());
}
Calling this function
List<Class> resultList = myFilter(sourceList, Class::getField, (a, b) -> a.equals(b), value);
Solution 3:[3]
Place the Stream processing into a dedicated method:
final <T> List<T> processStream( final Stream<T> initialData, final Predicate<T> predicate )
{
return initialData.stream()
.filter( predicate )
.collect( Collectors.toList() );
}
This allows you to specify the filter according to your needs:
Predicate<Data> predicate = d -> true; // Initial predicate does no filtering
processStream( initialData, predicate );
or this:
predicate = predicate.and(d -> d.hasData()); // Chain additional conditions
processStream( initialData, predicate );
You have to wrap the processing into a method (or otherwise), because predicate needs to be a constant in the scope of the lambdas you use with the Stream.
And of course, the error handling (null checks) is missing …
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | GhostCat |
| Solution 2 | |
| Solution 3 | tquadrat |
