Java8:不明白Java函数式接口的实现方式

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

假设我们有一个 Predicate 和一个 Function-接口:

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

现在我想给 Predicate 接口一个方法引用,其中 return 类型是 boolean,在我们的例子中参数是一个字符串。但是为什么下面的方法参考好像是对的:

Predicate<String> predicate = String::isEmpty;

isEmpty-方法没有字符串参数,尽管Predicate-接口需要字符串参数。为什么还是对的?我错过了什么吗?

另一个例子:函数接口return在我们的例子中是一个字符串,并接受一个字符串作为参数。但是下面的方法参考好像是错误的:

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

Concat 方法有一个字符串作为参数,returns 是一个字符串。为什么错了?

希望有人能给我解释一下。

当您在实例方法上使用方法引用时,方法接收者成为第一个参数。所以

String::isEmpty

相当于

(String str) -> str.isEmpty()

String::concat

相当于

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

...与 Function 的类型不匹配。

原因

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

不编译是因为它等同于(如 Louis 所写)

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

Function.apply(T t) 仅采用一个参数 (t),而您传递的函数采用两个参数 (ab)。

String::isEmpty 理论上可以表示以下两种情况之一。

  1. String中的一个静态方法class:

    s -> String.isEmpty(s)
    
  2. String中的一个实例方法class:

    (String s) -> s.isEmpty()
    

您的情况属于#2。

同样,String::concat 可以表示以下两种情况之一:

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

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

(但是,这不是一个 Function<String, String>,因为它没有恰好接受一个参数。但是,它是一个 BinaryOperator<String>。)