Zack Zack - 2 months ago 8
Java Question

Is there an elegant way of applying an array of filters in Java 8?

Is there a way to use

reduce
or a similar method to apply an array of filters to an array of objects?

Right now, I have this:

private void applyManyFilters(long[] initialData, LongPredicate... filters) {
LongStream stream = Arrays.stream(initialData);
for (LongPredicate filter : filters) {
stream = stream.filter(filter);
}
long[] dataToUse = stream.toArray();

// Use filtered data
}


A more elegant solution would look something like this:

private void applyManyFilters(long[] initialData, LongPredicate... filters) {
long[] dataToUse = Arrays.stream(filters).reduce(Arrays.stream(initialData), (a, b) -> a.filter(b)).toArray();

// Use filtered data here
}


Of course, the example above doesn't compile because both parameters to
reduce
need to be
LongPredicate
, not
LongStream
. I'm curious if the code above can be written in one line?

(P.S. Just to be clear, this is intended to be a question of how Java 8 works, not a question about style. I do agree that the one-line approach is not nearly as readable as the loop.)

Answer

I believe this is what you're looking for:

private void applyManyFilters(long[] initialData, LongPredicate... filters) {
    long[] dataToUse = Arrays.stream(initialData)
                             .filter(v -> Arrays.stream(filters)
                                                .allMatch(f -> f.test(v)))
                             .toArray();
    // Use filtered data
}