chiperortiz chiperortiz - 2 months ago 12
Java Question

Java 8 Pattern predicate using Stream - how variable is inferred?

I am reading "Java SE 8 for the Really Impatient" and I see some curious code. It's like this:

final Pattern pattern = Pattern.compile(".....");
final long count = Stream.of("Cristian","Daniel","Ortiz","Cuellar")
.filter(pattern.asPredicate())
.count();


I just thought that asPredicate method would be something like

public boolean asPredicate(String stringToMatch){
.....
}


But the real implementation is like this

public Predicate<String>asPredicate(){
return s -> matcher(s).find();
}


I know that I could use something like this which is perfectly legal:

final long count = Stream.of("Cristian","Daniel","Ortiz","Cuellar")
.filter(a->pattern.matcher(a).find())
.count();


But my question is how the stream passes the String to the Pattern instance? how "Cristian","Daniel","Ortiz","Cuellar" each are passed to the method
s -> matcher(s).find()
. I mean how the Strings are somehow passed and become the
s
variable of the asPredicate method.

Answer

The Predicate interface is a functional interface that defines one abstract method boolean test(T t) where T in this case is the String type, since you're filtering on a Stream<String>. In other words, the code is equivalent to:

final long count = Stream.of("Cristian","Daniel","Ortiz","Cuellar")
  .filter(new Predicate<String>() {
       public boolean test(String s) {
          return matcher(s).find();
       }
   })
  .count();