I try to apply a Predicate
from a Pattern
to a Stream
of String
values:
final var someString = "first\nsecond\nthird"
final var myPattern = java.util.regex.Pattern.compile("second");
final var sb = new java.lang.StringBuilder();
someString.lines()
.takeWhile(not(myPattern::asMatchPredicate))
.forEachOrdered(sb::append)
;
But the compiler refuses this with the error:
method asMatchPredicate in class java.util.regex.Pattern cannot be applied to given types
required: no arguments
found: java.lang.String
reason: actual and formal argument lists differ in length
But why? The predicate takes a String
(Predicate<String>
) and the takeWhile
method expects a Predicate<? extends String>
.
Effectively you're doing the following:
Predicate<String> predicate = myMatcher::asMatchPredicate;
The method reference means you're trying to implement your own Predicate<String>
instead of using the one returned by Pattern#asMatchPredicate()
. That cannot work in this case for two reasons:
Pattern#asMatchPredicate()
method accepts no arguments, but the Predicate#test(T)
method accepts a single argument.Pattern#asMatchPredicate()
method returns a Predicate<String>
, but the Predicate#test(T)
method returns a boolean
.Since the Pattern#asMatchPredicate()
method already returns a Predicate<String>
there's no reason to use a method reference here—just negate the returned value. In other words, you could do either:
.takeWhile(Predicate.not(myMatcher.asMatchPredicate()))
Or:
.takeWhile(myMatcher.asMatchPredicate().negate())