user3133542
user3133542

Reputation: 1715

Java 8: Do not understand the way Java implements Functional Interfaces

lets say we a Predicate and a Function-Interface:

Function<String, String> function = null;
Predicate<String> predicate = null;

Now I want to give the Predicate-Interface a method reference where the return type is a boolean and in our case the parameter a string. But why the following method reference seems to be right:

Predicate<String> predicate = String::isEmpty;

The isEmpty-method has no String-Parameter,although the Predicate-Interface requires a String-Parameter. Why it is still right? Am I missing something?

Another Example: The Function interface returns in our case a String and takes a String as parameter. But the following method reference seems to be wrong:

Function<String, String> function = String::concat;  //wrong

The Concat-Method has a String as Parameter and returns a String. Why its wrong?

Hopefully somebody can explain it to me.

Upvotes: 0

Views: 100

Answers (3)

Louis Wasserman
Louis Wasserman

Reputation: 198073

When you use a method reference on an instance method, the method receiver becomes the first argument. So

String::isEmpty

is equivalent to

(String str) -> str.isEmpty()

and

String::concat

is equivalent to

(String a, String b) -> a.concat(b)

...which does not match the type of Function.

Upvotes: 3

Joe C
Joe C

Reputation: 15684

String::isEmpty can, in theory, mean one of two things.

  1. A static method in the String class:

    s -> String.isEmpty(s)
    
  2. An instance method in the String class:

    (String s) -> s.isEmpty()
    

Your case falls into #2.

Similarly, String::concat can mean one of two things:

    (s1, s2) -> String.concat(s1, s2)

or

    (String s1, String s2) -> s1.concat(s2) // Your case

(However, this is not a Function<String, String>, as it does not take precisely one argument. It is, however, a BinaryOperator<String>.)

Upvotes: 0

Adam Siemion
Adam Siemion

Reputation: 16039

The reason why

Function<String, String> function = String::concat;

does not compile is because it is equivalent to (as Louis written)

Function<String, String> function = (String a, String b) -> a.concat(b);

while Function.apply(T t) takes only one argument (t) and you are passing a function that takes two arguments (a and b).

Upvotes: 0

Related Questions