Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java 8 can you pass a method into a filter

i have many filters calling methods of the streamed object and using String methods that take 1 parameter on the result:

String s = "aComarisonString";

stream().filter( p -> p.thisReturnsAString().startsWith(s) )
stream().filter( p -> p.thisReturnsAString2().startsWith(s) )
stream().filter( p -> p.thisReturnsAString().endsWith(s) )
stream().filter( p -> p.thisReturnsAString().contains(s) )

is there a way to generify the filter so it looks/works something like

.filter( compare(thisReturnsAString,contains(s) )
.filter( compare(thisReturnsAString2,endsWith(s) )
like image 578
user7322840 Avatar asked Jan 16 '17 10:01

user7322840


People also ask

What does filter method do in Java 8?

The filter() function of the Java stream allows you to narrow down the stream's items based on a criterion. If you only want items that are even on your list, you can use the filter method to do this. This method accepts a predicate as an input and returns a list of elements that are the results of that predicate.

Which methods can you use to filter and slice a stream in Java 8 +?

Streams Filtering & Slicing Basics: Java 8 Streams support declarative filtering out of elements along with the ability to slice-off portions of a list. Streams support four operations to achieve this – filter() , distinct() , limit(n) and skip(n) .

Can we use multiple filters in Java 8?

More filters can be applied in a variety of methods, such using the filter() method twice or supplying another predicate to the Predicate.


1 Answers

There are several ways, but I agree with @shmosel. There will be only little to no improvement in readability.

One of the possible solutions:

<V, P> Predicate<? super P> compare(Function<P, V> valueFunction, Predicate<V> matchPredicate) {
  return p -> matchPredicate.test(valueFunction.apply(p));
}

A call to that method would look like:

stream().filter(compare(P::thisReturnsAString, s -> s.endsWith(comparisonString)))

Where P is the type of your object. A slightly adapted variant, which might however lead to lots of overloaded methods:

<V, C, P> Predicate<? super P> compare(Function<P, V> valueFunction, BiPredicate<V, C> matchPredicate, C value) {
  return p -> matchPredicate.test(valueFunction.apply(p), value);
}

A call to that method could look like this:

stream().filter(compare(P::thisReturnsAString, String::endsWith, comparisonString))

No real gain here. Just an other way to write, what you wrote with more boilerplate code ;-)

EDIT: added the suggestion from @shmosel regarding Predicate vs Function

like image 192
Roland Avatar answered Sep 30 '22 13:09

Roland